Python 异步爬虫教程 (2024 更新版)
又到了每周爬虫优化环节?明明爬100个带1秒延迟的测试页同步要蹲一分半钟,多线程怕冲突怕堆资源、进程间通信又麻烦——没错,Python协程异步爬虫才是2024年IO密集型任务的黄金解!
1. 异步爬虫概述
1.1 为什么非异步不可?
爬虫的核心瓶颈从来不是CPU运算,而是网络/磁盘IO等待——比如你敲了一个requests.get(),接下来几十几百毫秒甚至几秒,程序就在原地“死等”服务器响应,啥也干不了。
而异步爬虫,会在某个任务等待IO时,立刻切去执行其他可运行的任务,把等待时间全用满!
1.2 三大核心优势
2. 核心极简入门(无公式版)
不用搞复杂的底层调度算法,先记住这三个关键词:
2.1 协程(Coroutine)
可以理解为「能暂停、能恢复、由程序员主动控制」的任务单元——类比成看电影:
- 同步线程:一部电影看到底,中途不接电话
- 协程:看电影暂停→接紧急电话→处理完挂掉→回到电影暂停的地方继续看
2.2 事件循环(Event Loop)
这是协程的「总调度员」,在后台一直循环做三件事:
- 检查所有协程:哪些是已经暂停但IO完成的(可以恢复)?哪些是刚启动可以运行的?
- 按规则选一个任务执行
- 任务执行到暂停点(
await),再回到循环
Python 3.7+ 提供了超方便的入口asyncio.run(),不用手动创建/关闭事件循环了!
2.3 async/await 语法糖
是让协程代码看起来像同步代码的魔法:
async def:告诉Python「这不是普通函数,是协程函数,调用后会返回协程对象,不会立刻执行」await:只能用在async def里,意思是「等这个异步操作完成再往下走,期间你去忙别的任务」
3. 主流异步HTTP工具:aiohttp
Python异步生态里用得最多的就是aiohttp,2024年最新3.9+版本体验更丝滑!
3.1 最基础的单页爬取
3.2 2024版3.9+值得用的小更新
- 默认开启HTTP/2支持(需手动确认依赖
h2已安装) - 优化了DNS解析的并发缓存
- 更细粒度的连接复用和超时控制
- 内置对
httpx.Response格式的兼容(方便迁移老代码)
4. 实战:高性能URL批量爬取
直接上一个带异常处理、并发控制、数据解析的完整脚本框架!
4.1 完整代码
5. 最佳实践避坑指南
5.1 防封IP是第一要务
除了上面代码里的limit_per_host,还可以加:
- 速率限制:用
aiolimiter库,限制每秒请求数 - 随机User-Agent:用
fake_useragent_async库 - 随机延迟:在
await fetch前加await asyncio.sleep(random.uniform(0.1, 0.5))
5.2 不要混用同步阻塞代码
如果在协程里调用requests.get()、time.sleep()、open()这种同步阻塞的东西,事件循环会被完全卡住,异步就白用了!
- 换对应的异步库:requests→aiohttp/httpx,time.sleep→asyncio.sleep,open→aiofiles
5.3 异步解析也很重要?
如果你的数据解析非常非常复杂(比如几万字的长文本、大量正则匹配),可以用:
asyncio.to_thread():把同步解析扔到线程池里跑(Python 3.9+内置)- 专门的异步解析库(比如
selectolax虽然是同步,但比bs4快10倍以上,小数据量/中等数据量直接用就行)
6. 快速性能对比(测试版10条延迟1秒URL)
直接用上面的实战脚本简化改一下同步/多线程版本测试:
注意:HOST_LIMIT要根据目标网站的robots.txt/实际反爬策略调整,不是越大越好!
7. 总结
2024年,Python协程异步爬虫已经是入门级但高效率的选择——不用懂复杂的底层,只要记住「用async def定义任务,用await挂起等待,用asyncio.run启动」,再配合aiohttp的连接池和异常处理,就能写出比同步快几十倍的爬虫!

