资讯专栏INFORMATION COLUMN

python爬取某趣阁小说(2.0),十分钟爬完一千六百章

My_Oh_My / 2829人阅读

摘要:返回每个章节的集合。爬取完成,共计用了分钟左右。判断使用还是使用变量来存放未变化的,若下次循环与相等,说明此次请求没有成功,,因为某些页面本身存在错误没有数据,则需要跳过。

python爬虫高效爬取某趣阁小说


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

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

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

import requestsfrom lxml import etreefrom time import sleepdef 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_listif __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 requestsfrom lxml import etreefrom getip import getipimport randomimport timeheaders= {        "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")

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/119991.html

相关文章

  • ☀️在完一周的朋友圈后,我发现了.......惊人⚠️秘密

    各位童鞋,大家好,我是? 在《⭐UI自动化工具轻松实现微信消息收发⚡朋友圈爬取⁉️》文末给童鞋们布置了一个作业,批量朋友圈爬取,不知道大伙们是否还有映像。 看到很多小伙伴们踊跃报名参与,不禁要给你们点个赞。考虑到很多小伙伴想做却做出来,这…贴心的我这不就来给你们公布参考答案啦? 对相关基础还不了解的童鞋请参考前文: 《⭐UI自动化工具轻松实现微信消息收发⚡朋友圈爬取⁉️》 《️❤️对比PyWi...

    Cympros 评论0 收藏0
  • Python3 爬虫 requests+BeautifulSoup4(BS4) 爬取小说网站数据

    摘要:刚学爬虫不久,迫不及待的找了一个网站练手,新笔趣阁一个小说网站。继续学习,有改进方案的欢迎提出来,一起交流。 刚学Python爬虫不久,迫不及待的找了一个网站练手,新笔趣阁:一个小说网站。 前提准备 安装Python以及必要的模块(requests,bs4),不了解requests和bs4的同学可以去官网看个大概之后再回来看教程 爬虫思路 刚开始写爬虫的小白都有一个疑问,进行到什么时候...

    taoszu 评论0 收藏0
  • HTML中的图片

    摘要:中的图片图片的三种格式适合照片,包含一千六百多种颜色,这是一种有损格式,因为照片缩小时会丢掉图像的一些信息不支持透明度文件比较小不支持动画支持上百种颜色,的图像。 HTML中的图片 < img src=> 图片的三种格式 JPG JPG适合照片,包含一千六百多种颜色,这是一种有损格式,因为照片缩小时会丢掉图像的一些信息 不支持透明度 文件比较小 不支持动画 PNG PNG支持上百种...

    godruoyi 评论0 收藏0
  • 爬虫数据库一些简单的设计逻辑

    摘要:所以要设计条队列,保存商品信息。数据更新问题有新商品进来,直接插入即可,如果是旧商品,那要不要更新数据库里的内容呢一般来说是可以更新的,但有种情况例外,就是你的数据库会有人去编辑的情况。 场景:爬取某商城的部分商品。 队列设计 这里至少需要爬取2种资源,一种是商品列表,一种是商品信息。所以要设计1条队列,保存商品信息URL。 爬虫1定期爬前N个列表页 URL,把里面的商品信息URL爬下...

    edagarli 评论0 收藏0
  • python爬虫:取某网站视频

    摘要:把获取到的下载视频的存放在数组中也可写入文件中,通过调用迅雷接口,进行自动下载。 把获取到的下载视频的url存放在数组中(也可写入文件中),通过调用迅雷接口,进行自动下载。(请先下载迅雷,并在其设置中心的下载管理中设置为一键下载)实现代码如下: from bs4 import Bea...

    番茄西红柿 评论0 收藏2637

发表评论

0条评论

最新活动
阅读需要支付1元查看
<