爬虫-多线程爬取小说

        前言:最近在找一本小说,能在盗版网站上观看,但是体验不佳,于是就有了将网页上的小说内容爬取到本地的想法。刚开始是单线程爬取小说(代码量少,逻辑简单(好吧,是我懒o.O)),后来发现爬个1千多章要差不多10分钟,头皮发麻。于是研究了一下多线程,结果速度是起飞了,但是内容被拆分成了每一个txt文件,且顺序不定(看线程心情的~~(lll¬ω¬)),这怎么看!!((╯‵□′)╯︵┻━┻),于是...↓

        正文:欸!老师!(超大声!ฅ>_<)我有个点子! (๑•̀ㅂ•́)و✧)windows系统中文件夹会根据文件名称进行排序,那不妨在保存每一章内容时以章节所在列表的下标来命名(章节列表从网站上爬取下来是有序的),然后使用工具将这些txt文件合并为一个txt文件。马上附上代码和工具!!! ฅ(๑ ̀ㅅ ́๑)ฅ 

import requests
import parsel
import os
from concurrent.futures import ThreadPoolExecutor


# 创建Novel类
class Novel:
    def __init__(self, url, headers):
        self.home_url = url
        self.headers = headers

    # 获取选择器
    def get_selector(self, url, headers):
        response = requests.get(url, headers=headers)
        response.encoding = 'utf-8'
        response = response.text
        selector = parsel.Selector(response)
        return selector

    # 获取小说名称
    def get_novel_name(self):
        html_selector = self.get_selector(self.home_url, self.headers)
        # xpath路径要自己动手喔ฅฅ*~
        novel_name = html_selector.xpath('').get()
        return novel_name

    #  获取小说章节url的id
    def get_chapter_ids(self):
        html_selector = self.get_selector(self.home_url, self.headers)
        # xpath路径要自己动手喔ฅฅ*~
        chapter_ids = html_selector.xpath('').getall()
        return chapter_ids

    # 获取小说章节名和内容
    def get_title_content(self, url):
        html_selector = self.get_selector(url, self.headers)
        # xpath路径要自己动手喔ฅฅ*~
        title = html_selector.xpath('').get()
        content = html_selector.xpath('').getall()
        content = '\n'.join(content)
        return title, content

    # 保存小说
    def save(self, url, chapter_index, save_path):
        title, content = self.get_title_content(url)
        print(title + '保存中...')
        # chapter_index:04这是将下标格式化,为了方便后续使用工具进行合并
        # 比如这时的chapter_index为1,那么格式化后就是0001
        with open(f'{save_path}\\{chapter_index:04} {title}.txt', 'w', encoding='utf-8') as f:
            f.write(title)
            f.write('\n')
            f.write(content)
            f.write('\n')
        print(title + '保存完毕')

if __name__ == '__main__':
    # 模拟浏览器
    # Cookie和User-Agent要自己动手喔ฅฅ*~
    headers = {
        'Cookie': '',
        'User-Agent': ''
    }
    # 目录页url
    home_url = ''
    # 实例化一个novel对象
    novel = Novel(home_url, headers)
    novel_name = novel.get_novel_name()
    chapter_ids = novel.get_chapter_ids()
    # 创建一个以小说名命名的文件夹,用于保存全部小说章节
    os.makedirs(f'{novel_name}', exist_ok=True)
    # 设置保存路径
    save_path = novel_name + '\\'
    # 线程池中的线程数量请根据个人设备进行调整
    with ThreadPoolExecutor(max_workers=100) as executor:
        for link in chapter_ids:
            # 保存该章节的下标
            chapter_index = chapter_ids.index(link) + 1
            # 章节url的组合需根据具体网页地址进行分析>.<
            link = home_url + link
            # 使用匿名函数传入多个参数
            executor.submit(lambda p:novel.save(*p), (link, chapter_index, save_path))
    print(f'{novel_name}保存完毕,共{len(chapter_ids)}章,( ๑╹ ꇴ╹) グッ~~拜拜')

工具:工具-合并多个txt文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值