吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3311|回复: 21
收起左侧

[Python 转载] 笔趣阁整书爬取

  [复制链接]
lys76 发表于 2022-6-29 17:40
[Asm] 纯文本查看 复制代码
import os
import parsel
import requests
from tqdm import tqdm
from random import randint
from time import time, sleep
from requests.exceptions import RequestException


class DownloadBiQuGe:
    """爬取笔趣阁:http://www.b5200.net或者org"""

    def __init__(self):
        self.novel_name = ''
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/95.0.4638.69 Safari/537.36'
        }
        if not os.path.exists('.\\笔趣阁'):
            os.mkdir('.\\笔趣阁')

    def __requestes(self, url, params=None):
        """获取网页数据"""
        with requests.get(url=url, headers=self.headers, params=params) as response:
            response.encoding = 'gbk'
        return response

    def get_url_data(self, url, params=None):
        """网络爬取处理异常"""
        try:
            return self.__requestes(url, params=params)
        except RequestException as e:
            print(f'\n爬取{url}时出现异常:{e}')
            del e
            seconds = randint(10, 30)
            print(f'休息 {seconds} 秒后重试...')
            sleep(seconds)
            try:
                print('开始重试...')
                return self.__requestes(url, params=params)
            except RequestException as e:
                print(f'\n爬取{url}时发生错误:{e}')
                del e
                print('重试后仍然无法解决,程序退出!')

    def get_table_of_contents_url(self, url):
        """
        获取小说的全部章节目录的url
        url:小说的目录网址
        返回小说所有章节的url列表
        """
        response = self.get_url_data(url)
        selector = parsel.Selector(response.text)
        urls_list = selector.css('#list dl dd a::attr(href)').getall()[9:]  # 0-8为最新章节
        # print(url_list)
        return urls_list

    def get_one_chapter(self, url):
        """爬取1个章节,调用保存函数"""
        response = self.get_url_data(url)
        if response:
            selector = parsel.Selector(response.text)
            title = selector.css('.bookname h1::text').get()  # 获取 章节标题
            table = title.maketrans(r'\*"/:?|<>', '         ')
            title = title.translate(table).replace(' ', '')
            contents = selector.css('#content p::text').getall()  # 获取 文章文本类容
            text = ''
            # print(contents)
            for i in contents:
                text += i.strip() + '\n'
            # print(text)
            if self.save_to_txt(title, text):
                print(f'{title}')

    def do_search_book(self, book_name):
        """搜索小说名或者作者名,并调用搜索结果显示函数,返回parsel.Selector"""
        url = f'http://www.b5200.org/modules/article/search.php'
        params = {
            'searchkey': book_name
        }
        response = self.get_url_data(url, params=params)
        selector = parsel.Selector(response.text)
        self.show_search_resul(selector)  # 调用搜索结果显示函数
        return selector

    @staticmethod
    def show_search_resul(selector):
        """显示搜索到的小说或作者名称"""
        resul_title = selector.css('.odd a::text').getall()
        if not resul_title:  # 没有搜索结果
            print('出错啦。没找到相关的小说或作者')
        else:
            resul_url = selector.css('.odd a::attr(href)').getall()
            resul_author = selector.css('.odd::text').getall()[::2]  # 只要作者,最后更新时间等不要
            # print(resul_title, resul_url, resul_author)
            resul_num = len(resul_title)  # 搜索结果 个数
            print(f'搜索到相关内容{resul_num}个:')
            for i in range(resul_num):
                print(f'{(i + 1)}. <<{resul_title[i]}>>\t作者:{resul_author[i]}\t 目录地址:{resul_url[i]}')

    @staticmethod
    def get_choose():
        """获取用户的选择,并返回选择的整数"""
        while True:
            choose = input('你要下载第几个?请选择:')
            if choose.isalpha() or choose.isspace():
                print('你的输入有误!请重新选择:')
            else:
                return int(choose) - 1  # 显示的时候加了1,这里需要减回来

    def get_search_key(self):
        """获取用户的输入书名或者作者名,返回搜索结果"""
        search_key = input('请输入您要下载的小说或作者的名称:')
        result = self.do_search_book(search_key)
        return result

    def save_to_txt(self, title, text):
        """保存文本"""
        try:
            with open(f'.\\笔趣阁\\{self.novel_name}\\{title}.txt', mode='w', encoding='utf-8') as f:
                f.write(text)
        except IOError as e:
            print(f'保存{title}.txt 时发生错误::{e}')
            return False
        except Exception as ee:
            print(ee)
        else:
            return True

    def task(self):
        """开启书本下载任务"""
        star_time = time()
        result = self.get_search_key()  # 会逐级返回搜索结果
        resul_url = result.css('.odd a::attr(href)').getall()  # 在搜索结果中取目录网址
        resul_title = result.css('.odd a::text').getall()  # 在搜索结果中取小说名
        choose = self.get_choose()  # 用户选择下载第几个

        self.novel_name = resul_title[choose]
        if not os.path.exists(f'.\\笔趣阁\\{self.novel_name}'):
            os.mkdir(f'.\\笔趣阁\\{self.novel_name}')

        urls_list = self.get_table_of_contents_url(resul_url[choose])  # 章节目录列表
        print(f'一共{len(urls_list)}章节,请耐心等待...')

        for url in tqdm(urls_list, colour='green'):
            self.get_one_chapter(url)
            sleep(0.85)
        print(f'任务完成.耗时{(time() - star_time):.2f}秒')


d = DownloadBiQuGe()  # 实列化
d.task()  # 开启任务

Snipaste_2022-06-29_17-39-55.png
Snipaste_2022-06-29_17-39-14.png

免费评分

参与人数 6吾爱币 +10 热心值 +5 收起 理由
cecum + 1 用心讨论,共获提升!
genon + 1 用心讨论,共获提升!
lxb888 + 1 用心讨论,共获提升!
manjuan + 1 + 1 谢谢@Thanks!
Syuns + 1 + 1 我很赞同!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

rangersxiaoyan 发表于 2022-7-14 12:19
写的不错,就是单线程太慢了。用多线程最好
请输入您要下载的小说或作者的名称:诡三国
搜索到相关内容2个:
1. <<诡三国>>        作者:马月猴年         目录地址:http://www.b5200.org/55_55592/
2. <<诡三国之摸金校尉的崛起>>        作者:源子夫         目录地址:http://www.b5200.org/50_50682/
你要下载第几个?请选择:1
一共2575章节,请耐心等待...
  0%|          | 0/2575 [00:00<?, ?it/s]人在梧桐下书友整理的诡三国时间线
  0%|          | 1/2575 [00:01<43:24,  1.01s/it]第一章其实东汉末年就一个字
  0%|          | 2/2575 [00:01<42:28,  1.01it/s]第二章其实古人不简单
  0%|          | 3/2575 [00:02<42:27,  1.01it/s]第三章各有各自的算盘
  0%|          | 4/2575 [00:04<44:31,  1.04s/it]第四章路要怎么走
  0%|          | 5/2575 [00:05<43:51,  1.02s/it]第五章吃是有条件的
  0%|          | 6/2575 [00:06<43:18,  1.01s/it]第六章旁支与主家
  0%|          | 7/2575 [00:07<42:57,  1.00s/it]第七章
  0%|          | 8/2575 [00:08<42:42,  1.00it/s]第八章
  0%|          | 9/2575 [00:09<42:41,  1.00it/s]第九章棋手还是棋子
  0%|          | 10/2575 [00:10<42:31,  1.01it/s]第十章士族的法则
  0%|          | 11/2575 [00:11<42:25,  1.01it/s]第十一章北邙山的故事
  0%|          | 12/2575 [00:12<42:19,  1.01it/s]第十二章董卓的发家史
  1%|          | 13/2575 [00:12<42:05,  1.01it/s]第十三章各下各的棋
  1%|          | 14/2575 [00:13<42:04,  1.01it/s]第十四章抢手的皇帝
  1%|          | 15/2575 [00:14<42:18,  1.01it/s]第十五章董卓进京
  1%|          | 16/2575 [00:15<42:15,  1.01it/s]第十六章历史的玩笑
  1%|          | 17/2575 [00:16<42:09,  1.01it/s]第十七章洛阳的故人
  1%|          | 17/2575 [00:17<44:17,  1.04s/it]

 楼主| lys76 发表于 2022-7-14 23:00
rangersxiaoyan 发表于 2022-7-14 12:23
两个建议
1、单线程太慢了。
2、文件保存不能用章节名。有特殊字符章节名就坏了。

整个网址限制访问速度,不支持多线程。
关于特殊字符已经过滤了的。
QQ截图20220714225929.png
 楼主| lys76 发表于 2022-6-30 00:15
ManaCola 发表于 2022-6-30 01:26
mark,收藏学习楼主
 楼主| lys76 发表于 2022-6-30 08:27
有大大能将单线程弄成多线程么?异步更巴适
hxiang 发表于 2022-6-30 08:46
有没有软件?这个不太好操作啊!
cfvgbhnj 发表于 2022-6-30 13:17
欢迎分析讨论交流,吾爱破解论坛有你更精彩!
识趣呀 发表于 2022-6-30 15:39
吾爱破解论坛有你更精彩
ballhou 发表于 2022-6-30 16:51
厉害厉害,膜拜大神
zhang515 发表于 2022-6-30 18:08
太666666666了吧
小鲁靠谱 发表于 2022-7-14 10:51
相当的不错啊  
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-27 09:14

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表