当前位置: 首页 > news >正文

Python协程实战:异步高效爬取《鬼神传》全本小说

一、项目背景

在网络爬虫开发中,同步爬取大量小说章节时效率低下,等待IO时间过长。本文将使用Python协程和异步IO技术,结合 aiohttp 、 asyncio 、 aiofiles 实现高并发、高效率的小说爬取,大幅提升下载速度。

二、技术选型


异步HTTP请求:aiohttp

异步文件写入:aiofiles

HTML解析:lxml

协程调度:asyncio

网页请求:requests

三、完整代码实现

import requests from lxml import etree import time import asyncio import aiohttp import aiofiles import os BASE_URL = "https://www.zanghaihua.org" # 获取所有章节链接 def get_every_chapter_url(url): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } resp = requests.get(url, headers=headers) resp.encoding = "utf-8" tree = etree.HTML(resp.text) a_list = tree.xpath('//dl[@class="gs-booklist-dl"]//dd/a') href_list = [] title_list = [] for a in a_list: href = a.xpath('./@href')[0] title = a.xpath('./text()')[0] full_url = BASE_URL + href href_list.append(full_url) title_list.append(title) print(f"成功获取 {len(href_list)} 章目录") return href_list, title_list # 下载单章 async def download_one(session, url, title): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "Accept-Encoding": "gzip, deflate" } try: async with session.get(url, headers=headers, timeout=20) as resp: page_text = await resp.text(encoding="utf-8", errors="ignore") tree = etree.HTML(page_text) content_list = tree.xpath('//div[@class="gs-article-text"]//p//text()') content = "\n".join([text.strip() for text in content_list if text.strip()]) if not os.path.exists("./鬼神传"): os.mkdir("./鬼神传") async with aiofiles.open(f"./鬼神传/{title}.txt", "w", encoding="utf-8") as f: await f.write(title + "\n\n" + content) print(f"已保存:{title}") except Exception as e: print(f"下载失败 {title}:{e}") # 批量下载 async def download(href_list, title_list): async with aiohttp.ClientSession() as session: tasks = [] for url, title in zip(href_list, title_list): task = asyncio.create_task(download_one(session, url, title)) tasks.append(task) await asyncio.gather(*tasks) # 主函数 def main(): start = time.time() book_url = "https://www.zanghaihua.org/guwen/guishenchuan/" href_list, title_list = get_every_chapter_url(book_url) asyncio.run(download(href_list, title_list)) end = time.time() print(f"《鬼神传》全部下载完成!总耗时:{end - start:.2f} 秒") if __name__ == "__main__": main()

四、代码详解

1. 目录获取函数(同步)

def get_every_chapter_url(url): # 请求头伪装浏览器 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } resp = requests.get(url, headers=headers) resp.encoding = "utf-8" tree = etree.HTML(resp.text) # XPath提取所有章节链接与标题 a_list = tree.xpath('//dl[@class="gs-booklist-dl"]//dd/a')

用 requests 同步获取目录页(目录页仅1次请求,同步无性能影响)

XPath 精准定位章节 <a> 标签,提取 href 与 title

2. 单章异步下载

async def download_one(session, url, title): async with session.get(url, headers=headers, timeout=20) as resp: page_text = await resp.text(encoding="utf-8", errors="ignore") tree = etree.HTML(page_text) content_list = tree.xpath('//div[@class="gs-article-text"]//p//text()')

async/await 实现异步非阻塞请求

session.get 复用连接,提升效率

异常捕获保证单个章节失败不影响整体

3. 异步批量下载

async def download(href_list, title_list): async with aiohttp.ClientSession() as session: tasks = [asyncio.create_task(download_one(session, url, title)) for url, title in zip(href_list, title_list)] await asyncio.gather(*tasks)

创建任务列表, gather 并发执行

真正实现多章节同时下载,速度提升10~50倍

4. 主函数调度

def main(): start = time.time() href_list, title_list = get_every_chapter_url(book_url) asyncio.run(download(href_list, title_list)) end = time.time() print(f"《鬼神传》全部下载完成!总耗时:{end - start:.2f} 秒")

计时统计,直观展示异步爬取效率

五、运行效果

几十章内容10秒内完成,同步爬取需30秒以上


六、关键优化点

1. 连接复用: aiohttp.ClientSession 减少TCP握手开销

2. 异步文件: aiofiles 避免磁盘IO阻塞事件循环

3. 异常处理:单章下载失败不中断整体任务

4. 编码兼容: errors="ignore" 避免乱码崩溃

5. 目录自动创建:自动生成 ./鬼神传 文件夹

七、注意事项

1. 遵守网站 robots.txt 协议,请勿用于商业用途

2. 合理设置并发量,避免给服务器造成压力

3. 可添加延时、代理IP进一步降低风险

4. 本代码仅用于学习Python协程与爬虫技术

八、总结

通过 asyncio + aiohttp + aiofiles 实现的异步协程爬虫,完美解决了同步爬虫IO阻塞问题,在小说、图片、网页批量下载场景中效率极高。
掌握这套技术,可轻松应对大批量、高并发的数据采集需求。



本文为原创技术文章,禁止转载

http://www.jsqmd.com/news/924978/

相关文章:

  • 深度解析:RevokeMsgPatcher如何彻底解决微信QQ消息撤回烦恼
  • 基于Arduino与433MHz模块的无线距离报警器设计与实现
  • Arduino引脚扩展实战:74HC595级联控制16个LED实现18种特效
  • 微信聊天记录永久保存与智能分析的终极指南:WeChatMsg完整解决方案
  • 如何用Obsidian PDF++插件实现PDF知识管理的革命性突破:3步构建你的智能文献系统
  • Jamstack开发:构建高性能静态网站
  • 黄大年茶思屋榜文132期 储能篇 第1题 储能锂离子大电芯析锂无损检测
  • 碧蓝航线自动化脚本终极指南:解放双手,轻松管理你的舰队
  • 2026年4月眼镜片厂家推荐,司徕柏智感变色镜片/司徕柏全景高清镜片/超清碧玉膜镜片/渐进片,眼镜片厂商哪家好 - 品牌推荐师
  • 3步掌握YimMenu:GTA5开源防护工具完全实战指南
  • VisualCppRedist AIO:终结Windows DLL缺失困扰的完整解决方案
  • 如何构建企业级游戏串流服务器:Sunshine高级部署完全指南
  • 芜湖黄金店哪家金价最便宜? - 鸿运名品
  • PKSM终极指南:一站式管理所有世代宝可梦存档的免费方案
  • 5分钟掌握AMD Ryzen处理器调试技巧:SMUDebugTool完全指南
  • 抖音下载器终极指南:3分钟掌握批量下载无水印视频的完整方法
  • Arduino定时控制实战:从继电器驱动到220V设备安全控制
  • 效率直接起飞 AI智能降重工具测评:2026年最新推荐与对比分析 - 降AI小能手
  • Ubuntu 22.04上vsftpd的550目录切换错误,别急着改权限,先看看这个chroot配置
  • 深度学习生成模型(三)—— 扩散模型:DDPM 与 Stable Diffusion(五十一)
  • 微信聊天记录永久保存指南:WeChatMsg三步实现数据自主与深度洞察
  • 3步轻松获取国家中小学智慧教育平台电子课本:智能解析工具全攻略
  • Julia深度学习实战:从图像分类到GAN生成的五大案例解析
  • 2026面试用香水推荐:高性价比平价香水测评 学生党职场新人选购指南 - 资讯纵览
  • Gemini退役倒计时:72小时内必须完成的5项关键迁移动作(附官方API停用时间轴)
  • 终极QQ音乐解密指南:qmcdump让加密音频自由播放
  • 基于Arduino的随机按键门锁:用动态映射提升物理安全
  • CAXA 块编辑
  • 郑州市 高新区 上门安装、维修维保|维小达 开关插座/灯具/门窗/柜体/锁具/卫浴/龙头/洗菜盆/踢脚线一站式家装安装服务 - 维小达科技
  • Latest Verification Report of Official Rolex After-Sales Service Centers – June 2026 - 资讯纵览