python爬虫之爬取笔趣阁小说升级版

python爬虫高效爬取某趣阁小说
这次的代码是根据我之前的 笔趣阁爬取 的基础上修改的,因为使用的是自己的ip,所以在请求每个章节的时候需要设置sleep(4~5)才不会被封ip,那么在计算保存的时间,每个章节会花费6-7秒,如果爬取一部较长的小说时,时间会特别的长,所以这次我使用了代理ip。这样就可以不需要设置睡眠时间,直接大量访问。

一,获取免费ip

关于免费ip,我选择的是站大爷。因为免费ip的寿命很短,所以尽量要使用实时的ip,这里我专门使用getip.py来获取免费ip,代码会爬取最新的三十个ip,并以字典的形式返回两种,如{'http‘:'ip‘},{'https‘:'ip‘}

!!!!!!这里是另写了一个py文件,后续正式写爬虫的时候会调用。

import requests
from lxml import etree
from time import sleep

def getip():
    base_url = 'https://www.zdaye.com'
    url = 'https://www.zdaye.com/dayProxy.html'
    headers = {
        "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"
    }

    res = requests.get(url, headers=headers)
    res.encoding = "utf-8"
    dom = etree.HTML(res.text)
    sub_urls = dom.xpath('//h3[@class ="thread_title"]/a/@href')

    sub_pages =[]
    for sub_url in sub_urls:
        for i in range(1, 11):
            sub_page = (base_url + sub_url).rstrip('.html') + '/' + str(i) + '.html'
            sub_pages.append(sub_page)
    http_list = []
    https_list = []
    for sub in sub_pages[:3]:
        sub_res = requests.get(sub, headers=headers)
        sub_res.encoding = 'utf-8'
        sub_dom = etree.HTML(sub_res.text)
        ips = sub_dom.xpath('//tbody/tr/td[1]/text()')
        ports = sub_dom.xpath('//tbody/tr/td[2]/text()')
        types = sub_dom.xpath('//tbody/tr/td[4]/text()')
        sleep(3)
        sub_res.close()

        for ip,port,type in zip(ips, ports,types):
            proxies_http = {}
            proxies_https= {}
            http = 'http://' + ip + ':' + port
            https = 'https://' + ip + ':' + port
            #分别存储http和https两种
            proxies_http['http'] = http
            http_list.append(proxies_http)

            proxies_https['https'] = https
            https_list.append(proxies_https)

    return  http_list,https_list

if __name__ == '__main__':
    http_list,https_list = getip()

    print(http_list)
    print(https_list)

二,具体实现

完整代码放在最后后面了,这里的 from getip import getip 就是前面获取ip部分。
这里我收集数十个常用的请求头,将它们与三十个IP随机组合,共可以得到300个左右的组合。

这里我定义了三个函数用于实现功能。
biquge_get()函数:输入搜索页面的url,关于搜索的实现是修改url中的kw,在main函数中有体现。
--------------------------返回书籍首页的url和书名。

get_list()函数:输入biquge_get返回的url。
---------------------返回每个章节的url集合。

info_get()函数:输入url,ip池,请求头集,书名。
---------------------将每次的信息保存到本地。

info_get()函数中我定义四个变量a,b,c,d用于判断每个章节是否有信息返回,在代码中有写足够清晰的注释。
这里我讲一下我的思路,在for循环中,我循环的是章节长度的十倍。a,b,c的初始值都是0。
通过索引,url=li_list[a]可以请求每个章节内容,a的自增实现跳到下一个url。但是在大量的请求中也会有无法访问的情况,所以在返回的信息 ' text1 ‘ 为空的情况a-=1,那么在下一次循环是依旧会访问上次没有结果的url。

这里我遇到了一个坑,我在测试爬取的时候会打印a的值用于观察,出现它一直打印同一个章节数‘340'直到循环结束的情况,此时我以为是无法访问了。后来我找到网页对照,发现这个章节本来就没有内容,是空的,所以程序会一直卡在这里。所以我设置了另外两个变量b,c。

1,使用变量b来存放未变化的a,若下次循环b与a相等,说明此次请求没有成功,c++,因为某些页面本身存在错误没有数据,则需要跳过。
2,若c大于10,说明超过十次的请求,都因为一些缘由失败了,则a++,跳过这一章节,同时变量d减一,避免后续跳出循环时出现索引错误

最后是变量d,d的初始值设置为章节长度,d = len(li_list),a增加到与d相同时说明此时li_list的所有url都使用完了,那么就需要跳出循环。
然后就是将取出的数据保存了。

最后测试,一共1676章,初始速度大概一秒能下载两章内容左右。

爬取完成,共计用了10分钟左右。

import requests
from lxml import etree
from getip import getip
import random
import time

headers= {
        "User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"
    }
'''
kw输入完成搜索,打印所有的搜索结果
返回选择的书籍的url
'''
def biquge_get(url):
    book_info = []
    r = requests.get(url =url,
                     headers = headers,
                     timeout = 20
                     )
    r.encoding = r.apparent_encoding
    html = etree.HTML(r.text)
    # 获取搜索结果的书名
    bookname = html.xpath('//td[@class = "odd"]/a/text()')
    bookauthor = html.xpath('//td[@class = "odd"]/text()')
    bookurl = html.xpath('//td[@class = "odd"]/a/@href')
    print('搜索结果如下:\n')
    a = 1
    b = 1
    for i in bookname:
        print(str(a) + ':', i, '\t作者:', bookauthor[int(b - 1)])
        book_info.append([str(a),i,bookurl[a-1]])
        a = a + 1
        b = b + 2
    c = input('请选择你要下载的小说(输入对应书籍的编号):')
    book_name = str(bookname[int(c) - 1])
    print(book_name, '开始检索章节')
    url2 = html.xpath('//td[@class = "odd"]/a/@href')[int(c) - 1]
    r.close()
    return url2,book_name

'''
输入书籍的url,返回每一章节的url
'''
def get_list(url):

    r = requests.get(url = url,
                     headers = headers,
                     timeout = 20)
    r.encoding = r.apparent_encoding
    html = etree.HTML(r.text)
    # 解析章节
    li_list = html.xpath('//*[@id="list"]/dl//a/@href')[9:]
    return li_list

#请求头集
user_agent = [
       "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)",
       "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
       "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
       "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
       "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
       "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
       "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
       "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
       "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
       "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
       "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
       "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
       "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",
       "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6",
       "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
       "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20",
       "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52"]
'''
参数:url,ip池,请求头集,书名
'''
def info_get(li_list,ip_list,headers,book_name):
    print('共计'+str(len(li_list))+'章')
    '''
    a,用于计数,成功请求到html并完成后续的存写数据才会继续请求下一个url
    b,在循环中存放未经过信息返回存储判断的a,用于与下一次循环的a作比较,判断a是否有变化
    c,若超过10次b=a,c会自增,则说明应该跳过此章节,同时d减一
    d,章节长度
    '''
    a = 0
    b = 0
    c = 0
    d = len(li_list)
    fp = open('./'+str(book_name)+'.txt', 'w', encoding='utf-8')
    #这里循环了10倍次数的章节,防止无法爬取完所有的信息。
    for i in range(10*len(li_list)):
        url = li_list[a]
        #判断使用http还是https
        if url[4:5] == "s":
            proxies = random.choice(ip_list[0])
        else:
            proxies = random.choice(ip_list[1])
        try:
            r = requests.get(url=url,
                             headers={'User-Agent': random.choice(headers)},
                             proxies=proxies,
                             timeout=5
                            )

            r.encoding = r.apparent_encoding
            r_text = r.text
            html = etree.HTML(r_text)
            try:
                title = html.xpath('/html/body/div/div/div/div/h1/text()')[0]
            except:
                title = html.xpath('/html/body/div/div/div/div/h1/text()')
            text = html.xpath('//*[@id="content"]/p/text()')
            text1 = []

            for i in text:
                text1.append(i[2:])

            '''
            使用变量b来存放未变化的a,若下次循环b与a相等,说明此次请求没有成功,c++,因为某些页面本身存在错误没有数据,则需要跳过。
            若c大于10,说明超过十次的请求,都因为一些缘由失败了,则a++,跳过这一章节,同时变量d减一,避免后续跳出循环时出现索引错误
            '''
            if b == a:
                c += 1
            if c > 10:
                a += 1
                c = 0
                d -=1
            b = a

            #a+1,跳到下一个url,若没有取出信息则a-1.再次请求,若有数据返回则保存
            a+=1
            if len(text1) ==0:
                a-=1
            else:
                fp.write('第'+str(a+1)+'章'+str(title) + ':\n' +'\t'+str(','.join(text1) + '\n\n'))
                print('《'+str(title)+'》','下载成功!')
            r.close()

        except EnvironmentError as e:
            pass
        # a是作为索引在li_list中取出对应的url,所以最后a的值等于li_list长度-1,并以此为判断标准是否跳出循环。
        if a == d:
            break
    fp.close()

if __name__ == '__main__':
    kw = input('请输入你要搜索的小说:')
    url = f'http://www.b520.cc/modules/article/search.php?searchkey={kw}'
    bookurl,book_name = biquge_get(url)
    li_list = get_list(bookurl)
    ip_list = getip()
    t1 = time.time()
    info_get(li_list,ip_list,user_agent,book_name)

    t2 = time.time()
    print('耗时'+str((t2-t1)/60)+'min')

到此这篇关于python爬虫之爬取笔趣阁小说升级版的文章就介绍到这了,更多相关python爬取笔趣阁内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python 爬取国内小说网站

    原理先行 作为一个资深的小说爱好者,国内很多小说网站如出一辙,什么

  • python爬取”顶点小说网“《纯阳剑尊》的示例代码

    爬取"顶点小说网"<纯阳剑尊> 代码 import requests from bs4 import BeautifulSoup # 反爬 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, \ like Gecko) Chrome/70.0.3538.102 Safari/537.36' } # 获得请求 def open_url(url):

  • python 爬取小说并下载的示例

    代码 import requests import time from tqdm import tqdm from bs4 import BeautifulSoup """ Author: Jack Cui Wechat: https://mp.weixin.qq.com/s/OCWwRVDFNslIuKyiCVUoTA """ def get_content(target): req = requests.get(url = target) r

  • Python爬取365好书中小说代码实例

    需要转载的小伙伴转载后请注明转载的地址 需要用到的库 from bs4 import BeautifulSoup import requests import time 365好书链接:http://www.365haoshu.com/ 爬取<我以月夜寄相思>小说 首页进入到目录:http://www.365haoshu.com/Book/Chapter/List.aspx?NovelId=3026 获取小说的每个章节的名称和章节链接 打开浏览器的开发者工具,查找一个章节:如下图,找到第一章的

  • Python爬虫入门教程02之笔趣阁小说爬取

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. 前文 01.python爬虫入门教程01:豆瓣Top电影爬取 基本开发环境 Python 3.6 Pycharm 相关模块的使用 request sparsel 安装Python并添加到环境变量,pip安装需要的相关模块即可. 单章爬取 一.明确需求 爬取小说内容保存到本地 小说名字 小说章节名字 小说内容 # 第一章小说url地址 url = 'http://www.biquges.co

  • Python scrapy爬取起点中文网小说榜单

    一.项目需求 爬取排行榜小说的作者,书名,分类以及完结或连载 二.项目分析 目标url:"https://www.qidian.com/rank/hotsales?style=1&page=1" 通过控制台搜索发现相应信息均存在于html静态网页中,所以此次爬虫难度较低. 通过控制台观察发现,需要的内容都在一个个li列表中,每一个列表代表一本书的内容. 在li中找到所需的内容 找到第两页的url "https://www.qidian.com/rank/hotsale

  • Python实现的爬取小说爬虫功能示例

    本文实例讲述了Python实现的爬取小说爬虫功能.分享给大家供大家参考,具体如下: 想把顶点小说网上的一篇持续更新的小说下下来,就写了一个简单的爬虫,可以爬取爬取各个章节的内容,保存到txt文档中,支持持续更新保存.需要配置一些信息,设置文档保存路径,书名等.写着玩,可能不大规范. # coding=utf-8 import requests from lxml import etree from urllib.parse import urljoin import re import os #

  • python爬虫之爬取笔趣阁小说升级版

    python爬虫高效爬取某趣阁小说 这次的代码是根据我之前的 笔趣阁爬取 的基础上修改的,因为使用的是自己的ip,所以在请求每个章节的时候需要设置sleep(4~5)才不会被封ip,那么在计算保存的时间,每个章节会花费6-7秒,如果爬取一部较长的小说时,时间会特别的长,所以这次我使用了代理ip.这样就可以不需要设置睡眠时间,直接大量访问. 一,获取免费ip 关于免费ip,我选择的是站大爷.因为免费ip的寿命很短,所以尽量要使用实时的ip,这里我专门使用getip.py来获取免费ip,代码会爬取最

  • python爬虫之爬取笔趣阁小说

    前言 为了上班摸鱼方便,今天自己写了个爬取笔趣阁小说的程序.好吧,其实就是找个目的学习python,分享一下. 一.首先导入相关的模块 import os import requests from bs4 import BeautifulSoup 二.向网站发送请求并获取网站数据 网站链接最后的一位数字为一本书的id值,一个数字对应一本小说,我们以id为1的小说为示例. 进入到网站之后,我们发现有一个章节列表,那么我们首先完成对小说列表名称的抓取 # 声明请求头 headers = { 'Use

  • Python爬虫之爬取最新更新的小说网站

    一.引言 这个五一假期自驾回老家乡下,家里没装宽带,用手机热点方式访问网络.这次回去感觉4G信号没有以前好,通过百度查找小说最新更新并打开小说网站很慢,有时要打开好多个网页才能找到可以正常打开的最新更新.为了躲懒,老猿决定利用Python爬虫知识,写个简单应用自己查找小说最新更新并访问最快的网站,花了点时间研究了一下相关报文,经过近一天时间研究和编写,终于搞定,下面就来介绍一下整个过程. 二.关于相关访问请求及应答报文 2.1.百度搜索请求 我们通过百度网页的搜索框进行搜索时,提交的url请求是

  • python爬虫爬取笔趣网小说网站过程图解

    首先:文章用到的解析库介绍 BeautifulSoup: Beautiful Soup提供一些简单的.python式的函数用来处理导航.搜索.修改分析树等功能. 它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序. Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码. 你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了.然后,你仅仅

  • Python爬虫之爬取二手房信息

    前言 说到二手房信息,不知道你们心里最先跳出来的公司(网站)是什么,反正我心里第一个跳出来的是网站是 58 同城.哎呦,我这暴脾气,想到就赶紧去干. 但很显然,我失败了.说显然,而不是不幸,这是因为 58 同城是大公司,我这点本事爬不了数据是再正常不过的了.下面来看看 58 同城的反爬手段了.这是我爬取下来的网页源码. 我们看到爬取下来的源码有很多英文大写字母和数字是网页源码中没有的,后来我了解到 58 同城对自己的网站的源码进行了文本加密,所以就出现了我爬取到的情况. 爬取二手房信息 我打开

  • Python爬虫实例爬取网站搞笑段子

    众所周知,python是写爬虫的利器,今天作者用python写一个小爬虫爬下一个段子网站的众多段子. 目标段子网站为"http://ishuo.cn/",我们先分析其下段子的所在子页的url特点,可以轻易发现发现为"http://ishuo.cn/subject/"+数字, 经过测试发现,该网站的反扒机制薄弱,可以轻易地爬遍其所有站点. 现在利用python的re及urllib库将其所有段子扒下 import sys import re import urllib

  • Python爬虫实现爬取京东手机页面的图片(实例代码)

    实例如下所示: __author__ = 'Fred Zhao' import requests from bs4 import BeautifulSoup import os from urllib.request import urlretrieve class Picture(): def __init__(self): self.headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleW

  • python爬虫之爬取百度音乐的实现方法

    在上次的爬虫中,抓取的数据主要用到的是第三方的Beautifulsoup库,然后对每一个具体的数据在网页中的selecter来找到它,每一个类别便有一个select方法.对网页有过接触的都知道很多有用的数据都放在一个共同的父节点上,只是其子节点不同.在上次爬虫中,每一类数据都要从其父类(包括其父节点的父节点)上往下寻找ROI数据所在的子节点,这样就会使爬虫很臃肿,因为很多数据有相同的父节点,每次都要重复的找到这个父节点.这样的爬虫效率很低. 因此,笔者在上次的基础上,改进了一下爬取的策略,笔者以

  • Python爬虫实现爬取百度百科词条功能实例

    本文实例讲述了Python爬虫实现爬取百度百科词条功能.分享给大家供大家参考,具体如下: 爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成.爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件.爬虫的工作流程较为复杂,需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列.然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页

随机推荐