爬取全网小说(1)

python爬取全网小说

前言:想必大家都有过看小说时突然弹出来广告的烦恼吧,今天我就来教大家怎么去下载用户指定的小说。

1. 分析页面
a) 我们首先找到小说的章节地址,分析发现每个小说都有一个唯一的编号。那我们只需要找到小说的编号即可下载所有的小说了。而正好我们可以使用字典将数据保存到本地,以小说名作为键,以小说的唯一编号作为值即可实现下载用户指定的小说了。
在这里插入图片描述
b) 我们知道了每个小说都有一个唯一的编号,找到编号即可下载对应的小说,那么编号到哪里找到呢。我们到小说的总排行榜的索引页中可以直接获取小说的唯一编号,我们只需要向索引页发送请求,提取其中的地址,然后再提取地址中的编号后进行拼接,这样我们就获取到小说章节的下载地址了。
在这里插入图片描述
2. 明确爬取目标
a) 我们分析网页得知在小说总排行榜中可以获取小说对应的唯一编号,拼接后就是小说章节的详情地址了。所以我们要爬取的目标就是总排行榜中所有小说的url。
在这里插入图片描述
b) 索引页的url变化。根据页数改变url即可获取所有小说的索引页url
在这里插入图片描述
3. 代码实现
a) 写爬虫的代码不重要,重要的思路,我只是给大家提供一种方法,更详情的讲解我会全放在代码中。

b) 完整代码

import json
import time
import requests
from os import path
from queue import Queue
from lxml import etree
from threading import Thread
from fake_useragent import UserAgent
from retrying import retry

class XiaoSshuoSpider(object):
    def __init__(self):
        self.url = 'http://www.55shuba.com/top/allvisit_{}.htm'
        self.headers = {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
                        "Accept-Encoding": "gzip, deflate",
                        "Accept-Language": "zh-CN,zh;q=0.9",
                        "Connection": "keep-alive",
                        "Cookie": "bdshare_firstime=1590149393888; UM_distinctid=1724548cc5b35-0819686bf4beda-58143718-144000-1724548cc5c2a7; CNZZDATA1254488625=180465324-1590297470-http%253A%252F%252Fwww.55shuba.com%252F%7C1590302884",
                        "Host": "www.55shuba.com",
                        "Referer": "http://www.55shuba.com/top/allvisit_1.htm",
                        "Upgrade-Insecure-Requests": "1",
                        "User-Agent": ua.random   # 使用random获取随机的用户代理
                        }
        self.queue = Queue()   # 创建先进先出队列
        self.info = {}         # 用来保存爬取后的数据
        self.count = 0         # 用来计数

    @retry(stop_max_attempt_number=3)   # retry的使用,当我们设置timeout三次都超时报错
    def get_url_title(self):
        while not self.queue.empty():      # 如果队列不为空就一直从队列中取出url并进行爬取
            res = requests.get(self.queue.get(), headers=self.headers, timeout=5).content.decode('gbk', errors='ignore')
            self.count += 1       # 计数
            print('正在爬取第{}页'.format(self.count))
            time.sleep(1)  # 爬取1个页面就睡眠1秒
            # 使用xpath提取小说名和小说的唯一编号
            html = etree.HTML(res)
            # 基准xpath提取数据
            dls = html.xpath('//div[@class="listtab"]//dl')
            for dl in dls:
                novel_name = dl.xpath('.//a/@title')[0]  # 提取小说名
                url_index = dl.xpath('.//a/@href')[0]    # 提取小说的url地址
                url_index = path.split(url_index)[-1][:-4]    # 从小说url地址提取出小说的编号
                '''例如:url = 'http://www.55shuba.com/txt/20394.htm
                        url_list = path.split(url_index)[-1]   # 得到的是一个元组,默认是以/为分隔符,而且是以最后面的/进行分割
                   分割后结果:('http://www.55shuba.com/txt', '20394.htm')
                '''
                self.info[novel_name] = url_index

    # 保存为json数据
    def save_data(self):
        with open('F:/文本/novel.json', 'w', encoding='utf-8')as f:
            f.write(json.dumps(self.info, ensure_ascii=False))
            print('保存完毕')


    def main(self):
        thread_list = []
        for i in range(1, 1863):   # 使用for循环创建将所有索引页的url放入队列中。
            self.queue.put(self.url.format(i))

        for i in range(10):        # 创建10个线程
            t1 = Thread(target=self.get_url_title)
            thread_list.append(t1)
            t1.start()

        for thread in thread_list:
            thread.join()


if __name__ == '__main__':
    start_time = time.time()
    try:
        ua = UserAgent()   # 实例化对象,调用其中的random即可获取随机的user-agent
        spider = XiaoSshuoSpider()
        spider.main()
        spider.save_data()
        print('花费{}s'.format(time.time()-start_time))
    except Exception as e:
        print('下载出错 {}'.format(e))

4. 注意事项

  1. 关于代码中使用的fake_useragent模块,你们第一次运行时可以会没有结果,过一会就会报这个错,如果大家有报这个错的可以参照我们的这一篇博客。–>报错点我<–
 fake_useragent.errors.FakeUserAgentError: Maximum amount of retries reached
  1. 这1862页的数据我是分了好几次进行下载的,然后再进行整理得到完整的数据,如果有小伙伴需要的话我这里提供了完整的json数据。大家可以依据自己的情况进行下载。
    链接:小说json数据
    提取码:2ktf

结语:我们实现了获取小说所对应的唯一编号,下一次我们就可以根据小说的编号下载全网的小说了。到这里可以说我们已经成功了一半了。大家可以根据我讲的自己去尝试一下下载小说。下篇文章我就会教大家怎么去下载小说。
第二篇地址:点我进入 爬取全网小说(2)

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值