Python多进程模块实战: 下载某小说网小说内容
练习一下Python的multiprocessing模块,成品代码如下:
#!/usr/bin/python3 # 书站爬虫 # 仅限学习多进程机制使用 使用后果全部由使用者自行承担. import requests import parsel from tqdm import tqdm from time import sleep import os from multiprocessing import Process, Value # 多进程中共享的变量 # 使用multiprocessing自带的Value q = Value('d', 0) #进程数 status = Value('d', 0) #运行锁 def new_sub_thread(func, args=()): # 多进程,启动! thread = Process(target=func, args=args, daemon=True) thread.start() def get_response(html_url, text_mode): headers = { 'User-Agent': 'Wget/1.21.1', 'accept-language': 'zh-CN,zh' } try: response = requests.get(url=html_url, headers=headers) except: # 失败重试(小的网络波动) sleep(2) try: response = requests.get(url=html_url, headers=headers) except: # 第二次重试(书站特有dns污染) sleep(4) response = requests.get(url=html_url, headers=headers) if text_mode == True: # 书站特有编码问题 标题和正文的编码不一样... response.encoding = response.apparent_encoding return response def save(novel_name, title, content): # 原始的保存机制... filename = f'{novel_name}' + '.txt' with open(filename, mode='w', encoding='utf-8') as f: # 写入标题 f.write(title) # 换行 f.write('\n') # 写入小说内容 f.write(content) # 换行 f.write('\n') def get_one_novel(name, novel_url, q, k, fulllen, status): # 下载某一章节的内容 #name: 小说名/ID, novel_url: 单章url, q: (共享)当前进程数, k: 下载章数, status: (共享)状态 0/1 q.value=q.value+1 #进程数+1 # 调用请求网页数据函数 response = get_response(novel_url, True) # 转行成selector解析对象 selector = parsel.Selector(response.text) # 获取小说标题 title = selector.css('.bookname h1::text').get() # 获取小说内容 返回的是list content_list = selector.css('#content::text').getall() # '\n'.join(列表) 把列表转换成字符串 并且带上换行 content_str = '\n'.join(content_list) save(name+'_tmp/'+str(k)+'_'+name, title, content_str) q.value=q.value-1 #进程数-1 if k == fulllen: status.value=1 #解运行锁 def get_all_url(html_url, novel_id, isreplace): # 调用请求网页数据函数 response = get_response(html_url, False) # 转行成selector解析对象 selector = parsel.Selector(response.text) # 所有的url地址都在 a 标签里面的 href 属性中 dds = selector.css('#list dd a::attr(href)').getall() # 小说名字 同时检测小说是否存在 try: novel_name = selector.css('meta[property="og:title"]::attr(content)').get() except: print("这本小说不存在...请检查ID是否正确") raise SystemExit() #手动退出 print("ID: "+str(novel_id)+" 标题: "+novel_name+" 章数: "+str(len(dds))) k = 1 #从1开算 if isreplace == 1: novel_id = novel_name os.system(f'mkdir {novel_id}_tmp') #缓存目录 for dd in tqdm(dds): while q.value == 8: # max 八进程 多了会等待结束一个进程后再继续 sleep(0.2) fulllen = len(dds) novel_url = base_url + dd new_sub_thread(get_one_novel, (novel_id, novel_url, q, k, fulllen, status)) sleep(0.2) k = k+1 while status.value == 0: sleep(1) #死循环直到跑完 while q.value != 0: sleep(0.5) #等待跑完 file1 = open(f'{novel_id}.txt', 'w') for i in range(1, len(dds)+1): f = open(f'{novel_id}_tmp/{i}_{novel_id}.txt') file1.write(f.read()) f.close() file1.close() os.system(f'rm -r {novel_id}_tmp') print("下载完成!") def main(): novel_id = input('输入锡海小说网的ID: ') global base_url #base_url = input('输入主站Url(eg: https://www.otcwuxi.com): ') base_url = 'https://www.otcwuxi.com' print("主站Url已默认: https://www.otcwuxi.com") url= base_url + '/chapter/' + novel_id + '/' isreplace = 1 #是否将小说文件名改为小说名字 get_all_url(url, novel_id, isreplace) if __name__ == '__main__': main()
仅限学习多进程机制使用,使用后果由使用者自行承担。因特殊原因本文章不接受评论。
--------------
你已经看完这篇博文了!
本文来自博客园,作者:星如雨yu,转载请注明原文链接:https://www.cnblogs.com/tianpanyu/p/17689345.html
另,建议转载手动看一眼,把代码块转过去呗(超小声嘀咕)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~