aiohttp本身单次请求不比requests快,甚至略慢;其高效源于并发时复用i/o等待时间,使100个请求总耗时接近最慢单个响应延迟(如2秒),而非串行累加(如200秒)。

为什么 aiohttp 本身不比 requests “快”,只是并发时更高效
很多人以为换用 aiohttp 就自动变快,其实不然:单次请求,aiohttp 和 requests 耗时几乎一样,甚至略慢;真正提速靠的是并发——在等待网络 I/O 时复用线程,让 CPU 不干等。如果你只发 1 个请求,或者用 asyncio.run() 串行 await 每个 session.get(),那和 requests.get() 没区别,还多一层协程调度开销。
关键判断点:只有批量请求、高延迟、低 CPU 计算的场景下,aiohttp 才有明显优势。比如爬 100 个网页(平均响应 300ms),用 requests 串行要 30 秒,而 aiohttp 并发 20 路通常 1.5~3 秒能完成。
必须用 ClientSession,且生命周期要管好
aiohttp.ClientSession 不是“每次请求 new 一个”就完事的。它内部维护连接池、DNS 缓存、Cookie jar,如果在循环里反复创建销毁,不仅无法复用 TCP 连接,还会触发大量 DNS 查询和 TLS 握手,性能反而暴跌。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 正确做法:整个爬虫生命周期只创建 1 个
ClientSession,用async with session:包裹所有请求 - 错误写法:
async with aiohttp.ClientSession() as session:写在 for 循环内 → 每次都新建 session - 别漏掉
connector配置:默认最多 100 个空闲连接,但并发数超过这个值会排队;建议显式设aiohttp.TCPConnector(limit=100, limit_per_host=30) - 记得加
timeout:不设超时,某个请求卡死会导致整个协程挂住;推荐aiohttp.ClientTimeout(total=10)
别直接 await response.text(),小心内存和编码崩
response.text() 是个协程方法,但它会把整个响应体读进内存再解码——遇到大文件(比如 PDF、图片、未压缩 HTML)极易 OOM;而且默认用 UTF-8 解码,若服务端返回 Content-Type: text/html; charset=gbk 却没声明,text() 会抛 UnicodeDecodeError。
- 稳妥做法:先
await response.read()拿 bytes,再用chardet.detect()或response.charset判定编码,手动 decode - 流式处理大响应:用
async for chunk in response.content.iter_chunked(8192):边收边处理,避免全加载 - 如果只要状态码或 header,根本不用
.text()或.read(),直接访问response.status和response.headers
并发控制不当,反而被目标站封或压垮自己
开 1000 个并发看着很猛,实际往往适得其反:目标服务器可能限速、封 IP;本地也容易触发 OSError: [Errno 24] Too many open files(Linux 默认 ulimit 1024);DNS 解析也可能成为瓶颈。
- 合理并发数:从 10~20 开始测,观察成功率和响应时间拐点;一般 30~50 对多数网站够用
- 加随机 delay:用
asyncio.sleep(random.uniform(0.1, 0.5))避免请求洪峰,降低被拦截概率 - 务必设 User-Agent:
headers={'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) ...'},否则很多站直接 403 - 注意 DNS 缓存:
aiohttp.TCPConnector(use_dns_cache=True, ttl_dns_cache=300)能减少重复解析
真正的瓶颈常不在代码,而在你没意识到的系统限制(文件描述符、DNS、本地带宽)和目标站的反爬策略。跑之前先用 curl -v 看单个请求的 headers 和 timing,再对比 aiohttp 的表现,才能知道哪块真拖后腿。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










