httpx 支持异步 IO 和 HTTP/2 协议,requests 仅支持同步请求。在 IO 密集型高并发场景下,httpx 的异步模式通常能获得更高的吞吐量,但需要配合 async/await 语法使用。
先说结论:性能差异主要源于并发模型而非单请求速度,选型需匹配场景。
- 适合:高并发 IO 任务选 httpx 异步模式,简单脚本或低并发选 requests。
- 重点看:事件循环管理机制和代理配置格式差异。
- 别忽略:httpx 的 HTTP/2 功能需额外安装依赖包。
命令速用版
快速处理思路:控制变量对比。保持目标 URL、网络环境、并发数量一致,分别编写同步和异步脚本,记录总耗时和资源占用。
# 安装基础库
pip install requests httpx
# 如需启用 httpx 的 HTTP/2 支持
pip install httpx[http2]为什么会这样
同步库阻塞线程,异步库非阻塞。requests 发起请求时线程会等待响应,CPU 空闲;httpx 异步客户端在等待 IO 时切换执行其他任务,提高 CPU 利用率。
requests 基于 urllib3 构建,设计哲学是“开箱即用”,适合单次请求或简单脚本。httpx 在继承 requests 优雅 API 的同时,补上了异步支持和 HTTP/2 协议两块短板,面向 Python 3.8+ 开发。
分步处理
1. 环境准备:安装库 pip install requests httpx。如需 HTTP/2,执行 pip install httpx[http2]。
2. 编写同步脚本:使用 requests.get 循环请求,记录开始和结束时间。适用场景:低频采集、调试接口。
3. 编写异步脚本:使用 httpx.AsyncClient 配合 asyncio.gather 并发请求,记录耗时。适用场景:高并发爬虫、实时数据处理。
4. 控制并发数:requests 使用线程池控制并发(最大线程数建议 50 左右),httpx 使用信号量或连接池限制并发(最大并发可设 200 以上)。
5. 风险边界:异步代码需在 asyncio.run 中执行,不能在同步函数内直接 await,否则报错。
怎么验证是否生效
检查总耗时、CPU 占用率和内存峰值。高并发下异步脚本总耗时应显著低于同步脚本,且 CPU 等待时间更少。
验证动作:在同一硬件环境(如 4 核 8G 服务器)下,对同一静态 API 发起 10 万级请求,对比两者完成时间。
验证结果:若 httpx 异步模式总耗时明显缩短且无大量报错,说明并发策略生效。
常见坑
1. 代理配置格式:requests 接受 http 键名,httpx 必须为 http:// 完整 scheme。迁移代码时 90% 的代理问题源于键名缺少//后缀。
2. 事件循环冲突:异步代码需在 asyncio.run 中执行,不能在同步函数内直接 await。
3. 依赖缺失:未安装 http2 依赖时,httpx 默认使用 HTTP/1.1,无法发挥协议优势。
常见问题
httpx 和 requests 能一起用吗?
可以共存。两者命名空间不同,但建议同一项目统一风格,避免混合使用增加维护成本。
httpx 异步一定比 requests 快吗?
不一定。单请求场景下差异不明显,高并发 IO 场景下异步优势才显著。
参考来源
- Python 中的 requests 和 httpx 对比详解
- requests/httpx/Playwright 性能实测:10 万条数据爬取该选谁?(附耗时/内存/CPU 全对比 + 代码)
- 《requests vs httpx:Python 网络请求库的全面对比与实战指南》
- Python 爬虫避坑指南:httpx 代理配置的正确姿势 (附 requests 对比)
- 【python_并发】requests vs aiohttp vs httpx:HTTP 客户端深度对比与实战