requests并发慢的根源是未使用session和连接池,应配置httpadapter的pool_connections与pool_maxsize、设置timeout元组、禁用压缩并添加合理user-agent。

requests并发太慢?别硬扛,用Session+连接池压测前先调对参数
单个 requests.get() 默认每次新建TCP连接、不复用,高并发下DNS解析+握手开销直接拖垮速度。不是代码写得不对,是没配 Session 和底层连接池。
实操建议:
- 所有批量请求必须用
requests.Session()实例,而不是反复调用requests.get() - 显式配置连接池:
session = requests.Session(); adapter = requests.adapters.HTTPAdapter(pool_connections=10, pool_maxsize=20),再session.mount('https://', adapter) -
pool_connections控制「可复用的域名连接池数量」,pool_maxsize是每个池里最大空闲连接数,别设成100——OS文件描述符会爆 - 超时必须设:
session.get(url, timeout=(3, 7)),元组第一个是connect timeout,第二个是read timeout,不设就卡死
异步发请求?别急着换aiohttp,先看是不是CPU/IO瓶颈混了
用 asyncio + aiohttp 的前提是:你真被IO卡住,而不是解析HTML或JSON时在主线程跑正则、嵌套循环、没用 ujson。
常见错误现象:
- 开了100个协程,但CPU跑满90%——大概率是响应体太大,你在用
response.json()解析几MB数据 - 并发一上去就报
RuntimeError: Event loop is closed——漏了await session.close()或用了全局未管理的ClientSession - 请求发出去了,但返回全是
429 Too Many Requests——网站反爬没加sleep,异步反而加速触发限流
如果只是几十个URL轮询,concurrent.futures.ThreadPoolExecutor 配合 Session 更稳,线程数控制在 min(32, os.cpu_count() + 4) 就够用。
API返回403/401但Postman能通?检查headers里User-Agent和Accept-Encoding是否被过滤
很多API网关(比如Cloudflare、Akamai)默认拦截无 User-Agent 或带 gzip 的请求,requests 默认发的 Accept-Encoding: gzip, deflate 反而成了特征。
使用场景:调内部测试API、爬公开数据接口、对接老系统文档不全的后端。
实操建议:
- 加一个合理
User-Agent:headers={'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'} - 禁用压缩:
headers['Accept-Encoding'] = 'identity',避免服务端因解压失败直接拒掉 - 某些API校验
Origin或Referer,得补全——但注意别暴露真实来源 - 如果带Token,确认是
Authorization: Bearer xxx还是X-API-Key: xxx,大小写和服务端要求严格匹配
响应体大、字段多?别用response.json()硬转,流式解析更省内存
当API返回几百KB以上JSON(比如日志列表、商品全量数据),response.json() 会把整个响应体读进内存再解析,容易OOM;尤其配合多线程/协程时,内存增长是乘法级的。
性能影响明显:100个2MB响应同时解析,可能吃掉200MB+内存,GC压力陡增。
实操建议:
- 用
response.iter_lines()处理NDJSON(每行一个JSON对象) - 大JSON数组用
ijson.parse()(需装ijson)边读边取字段,不加载全文本 - 如果只是取几个字段,考虑用
json.loads(response.content[:1024], parse_float=str)先截断预览结构 - 千万别在循环里写
json.dumps(data, indent=2)调试——格式化开销比解析还大
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











