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

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2791|回复: 39
收起左侧

[Python 转载] 优化了一下坛友的多线程爬取小说的代码

  [复制链接]
wapys 发表于 2022-11-20 13:15
本帖最后由 wapys 于 2022-11-20 16:49 编辑

连续采集一万多章节,基本无错误
原贴链接:【Python爬虫】用多线程爬取小说,下载速度快了N倍! - 『编程语言区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

只是测试了程序里的这个网站,其他的没做测试!
小改了一下,代码如下:
[Python] 纯文本查看 复制代码
import  requests
import shutil
import re,time
from lxml import etree
from concurrent.futures import ThreadPoolExecutor
import os
# ---------------------------------------------------------------------------------
# 支持站点:
# 八一中文网(81zw.com)
# 顶点小说(23usp.com)
#笔趣阁(bqg.org,qbiqu.com,52bqg.net等全部站点)
#天籁小说(xs.23sk.com)
# --------------------------------------------------------------------------------
if not os.path.exists('./缓存'): #创建缓存文件夹来存放抓取的每一章节文件
    os.mkdir('./缓存')
    # 下面这三行如果下载一部分,没下载完那就可以 注释掉 再运行!下面有已下载检查,下载过的章节不用重复下载           
else:  #如不存在则创建文件夹,如存在则清空再创建
    shutil.rmtree('./缓存')
    os.mkdir('./缓存')
url='https://www.23usp.com/xs_1511/'
# url='https://www.81zw.com/book/40352/'
# url='https://www.bqg.org/2_2977/'
# url='https://www.qbiqu.com/0_1/'
# url='https://www.52bqg.net/book_99524/'
# url='https://xs.23sk.com/files/article/html/22/22295/'
reg='(https://.*?)\/'
if '23usp' in url or '81zw' in url or '23sk' in url:
    homeUrl=re.findall(reg,url,re.S)[0]
else:
    homeUrl=url 
headers={
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0'
}
def choiceCode(homeUrl): 
    if '23usp' in homeUrl or '23sk' in homeUrl: #转码,否则有乱码
        return 'gbk'
    elif '81zw' in homeUrl:
        return 'utf-8'
    else:
        return 'GB2312'
homePage=requests.get(url=url,headers=headers) #抓取主页面html数据
homePage.encoding=choiceCode(homeUrl)          #转码
tree=etree.HTML(homePage.text)
zhangJie_list=tree.xpath('//dd//a/@href') #获取每一章的页面相对地址
title=tree.xpath('//h1/text()')[0] #获取小说名字
zjNameList=[]
zhangJie_list=list(set(zhangJie_list)) #去重
for u in zhangJie_list: #每一章的URL地址中提取一串数字作为存储每一章的文件名
    zhangjietxtname=u.split('/')[-1].split('.')[0]
    zjNameList.append(int(zhangjietxtname))
zjNameList.sort() #章节排序
def downtxt(url): #下载每一章的函数
    zhangjie_url=homeUrl+url
    txtName=url.split('/')[-1].split('.')[0] #获取每一章URL地址中的一串数字作为文件名字
    if os.path.exists('./缓存/{}.txt'.format(txtName)): #这里是查重,如果有重复文件就不继续采集了
        print(zhangjie_url,"\n 已采集,执行下一个")           
    else:  
        try:
            zhangjie_sourse=requests.get(url=zhangjie_url,headers=headers)
            zhangjie_true = None  #这一句是记录是否采集成功
        except:
            for i in range(6):
                time.sleep(5)    # 采集错误的一次停止5秒再试
                try:                                    
                    zhangjie_sourse=requests.get(url=zhangjie_url,headers=headers)                    
                    zhangjie_true = None #这一句是记录是否采集成功
                    break #如果没出错跳出循环,否则继续循环
                except:
                    i += 1 
                    print(url+' '*10+'第%s次下载失败'%i)    # 记录失败了多少次,大于六次就退出               
                    
            if zhangjie_true != None: 
                with open('./错误网址.txt','a',encoding='utf-8') as f:
                    f.write(url+'\n')
                print(url+' '*10+'下载失败')          #采集错误的记录在这个文件里
            # pass
        if zhangjie_true == None:
            zhangjie_sourse.encoding = choiceCode(homeUrl) #章节页面内容转码
            zhangjie_sourse=zhangjie_sourse.text
            tree=etree.HTML(zhangjie_sourse)
            title=tree.xpath('//h1/text()')[0] #获取每一章名字
            txt=tree.xpath('//div[@id="content"]/text()') #获取每一章文本内容
            with open('./缓存/{}.txt'.format(txtName),'w',encoding='UTF-8') as f:
                f.write('\n'+title+'\n') #保存章节名字到文本文件
                for line in txt: #保存章节内容到文本文件,循环保存每一行
                    f.write(line)
                print(title+' '*10+'下载成功')
        else:
            print(url+' '*10+'下载失败')
def combine_txt():  #合并所有章节文件函数
    with open('./{}.txt'.format(title),'a',encoding='utf-8') as f:
        for txt in zjNameList: #循环打开缓存中每一章的内容保存到新的文件中
            path='./缓存/{}.txt'.format(txt)  #设置存放路径
            content=open(path,'r',encoding='utf-8').read() #打开每章节文件
            f.write(content)
            os.remove(path)
def mistake_txt(): # 这个函数把错误网址在合并文件前再重新采集一遍
    with open('./错误网址.txt','w+',encoding='utf-8') as f:
        ff = f.readlines()
        ii = len(ff)
        print("共{}条数据。".format(ii))
        print("-"*30)
        if ii>0:
            i = 1
            for line in ff:
                print("下面采集第 {} 条数据。".format(i))
                downtxt(line)
                i += 1
            print("错误网址已经采集完毕!")
        else:
            
            print("你没有、没有出错网址!")
        print("-"*30)
with ThreadPoolExecutor(15) as Pool: #使用线程池,设置15个线程,可修改
    Pool.map(downtxt,zhangJie_list)
print('!!!下载完毕,开始检查有没有错漏章节,请稍等。。。!!!')
mistake_txt()
print('!!!下载完毕,开始合并,请稍等。。。!!!')
combine_txt() #执行合并函数
os.removedirs('./缓存') 
print('!!!全部完成!!!!')

重新修改了一下注释!方便调用!

免费评分

参与人数 4吾爱币 +3 热心值 +3 收起 理由
lingwushexi + 1 + 1 谢谢@Thanks!
MikC + 1 学到了
xiaoyu0307 + 1 学到了
Javajpa + 1 + 1 热心回复!

查看全部评分

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

 楼主| wapys 发表于 2023-3-12 10:45
聚散流沙 发表于 2023-3-11 22:36
纯小白 突然想找点小说看就研究研究

[Python] 纯文本查看 复制代码
for line in txt: #保存章节内容到文本文件,循环保存每一行
                    f.write('\n'+line)


这里加个换行就可以了!
ok667 发表于 2023-4-5 09:43
请教,http://www.dpxq.com/hldcg/search/view_u_1837066.html
这样的页面怎么爬取里面的UBB代码?
网页只需换数字。可以加微信请教吗?
Javajpa 发表于 2022-11-20 15:17
lilovehistory 发表于 2022-11-20 15:37
快快学习
qq327594197 发表于 2022-11-20 15:37
强啊,有学到了
hotzhangany 发表于 2022-11-20 15:42
大佬NB,感谢分享
zjxuan 发表于 2022-11-20 15:54
免费,强悍PY代码。。
 楼主| wapys 发表于 2022-11-20 16:52
重新加了注释!其实这样感觉用协程加异步会更快!
ccxxqq 发表于 2022-11-21 00:04
收到,好好学习,谢谢楼主
kevinchenyuan 发表于 2022-11-21 00:08
强啊,有学到了
ywsl 发表于 2022-11-21 02:42
感谢大佬的修改
您需要登录后才可以回帖 登录 | 注册[Register]

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

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

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

GMT+8, 2024-5-17 05:44

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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