requests慢是因为默认不复用TCP连接、不缓存DNS、SSL握手开销大;优化需用Session复用连接、合理设置超时、按需关闭重定向和SSL验证。

requests 为什么慢?先看默认行为
requests 默认每次请求都新建 TCP 连接,不复用;DNS 解析也默认不缓存;SSL 握手开销在 HTTPS 场景下尤为明显。这些不是 bug,而是为简单性做的取舍。如果你批量调用同一域名的接口(比如爬取分页、轮询 API),requests.get() 直接写循环,大概率会卡在连接建立阶段。
用 Session 复用连接和 Cookie
requests.Session() 是最简单也最有效的优化起点。它自动复用底层 urllib3.PoolManager 的连接池,避免重复握手和 DNS 查询。同时能统一管理 headers、auth、cookies,减少重复传参。
实操建议:
- 单次请求不用改;高频/批量请求必须提取出
Session实例,复用整个生命周期 - 显式设置连接池大小:例如
session = requests.Session(); adapter = requests.adapters.HTTPAdapter(pool_connections=10, pool_maxsize=20),再用session.mount("https://", adapter) - 注意:
Session不是线程安全的,多线程中每个线程应持有独立实例,或加锁
禁用重定向和 SSL 验证(仅限可信环境)
重定向(allow_redirects=True 默认)会额外发起请求;SSL 验证(verify=True 默认)涉及证书链校验和 OCSP 查询,在内网或测试环境纯属冗余开销。
立即学习“Python免费学习笔记(深入)”;
常见错误现象:requests.get("https://api.example.com") 卡住几秒才返回,但 curl -k 瞬间响应 —— 很可能就是 SSL 验证拖慢了。
使用场景与风险提示:
- 内网服务、本地开发、Docker 容器间调用:可安全设
verify=False(记得加requests.packages.urllib3.disable_warnings()抑制警告) - 跳转逻辑明确且可控时,设
allow_redirects=False,自己处理response.status_code == 302和response.headers["Location"] - 生产环境绝不关闭
verify,除非你自建 CA 并配置verify="/path/to/cert.pem"
超时必须设,且要拆分成 connect + read
不设超时的 requests 调用,在网络抖动或服务假死时会无限阻塞主线程。更糟的是,只设一个 timeout=5 无法区分是连不上,还是连上了但迟迟不发数据。
性能影响很直接:没设 connect 超时,DNS 失败或目标端口未监听可能卡 60+ 秒;没设 read 超时,对方写一半就挂起,你永远等不到 EOF。
正确姿势:
- 始终使用元组形式:
requests.get(url, timeout=(3.0, 8.0)),前者是连接超时,后者是读取超时 - 连接超时建议 ≤ 3s(DNS + TCP handshake);读取超时按业务容忍度设,一般 5–15s
- 不要依赖
timeout做逻辑兜底,它只抛requests.exceptions.Timeout,不解决重试问题
真正影响吞吐量的,往往不是单次请求快 10ms,而是连接复用是否到位、超时是否合理、以及你有没有把阻塞操作(比如日志写入、JSON 解析)塞进请求循环里。这些细节不显眼,但一不留神就会让并发能力掉一个数量级。











