requests 超时参数深度解析

🕵️ Python requests 中 timeout 的坑:连接超时与读取超时的那些事

最近在使用 Python 的 requests 库抓取数据时,遇到一些很“玄学”的超时错误。明明设置了合理的 timeout,请求依然抛出 Read timed out,而且有时是在连接阶段就失败了。这让我决定做一次系统的实验,深入理解 requests 的 timeout 参数到底怎么回事。


⏱ timeout 参数到底指什么?

requests.get(url, timeout=(连接超时, 读取超时))

timeout 参数有两种写法:

  • timeout = 5:连接和读取加起来 5 秒,一刀切;
  • timeout = (5, 10):连接最多等 5 秒,连接成功后读取最多等 10 秒。

所以:

requests.get("https://example.com", timeout=(3, 10))

意思是:最多等 3 秒连上服务器,连上之后最多再等 10 秒读取数据。


🧪 实验:谁在超时?

我选择了一个会延迟 8 秒才返回的地址:
https://httpbin.org/delay/8

然后用如下代码跑了一组测试:

import requests

def debug_timeout(timeout):
    try:
        requests.get("https://httpbin.org/delay/8", timeout=timeout)
    except Exception as e:
        print(f"[DEBUG] Caught exception: {e}")

test_examples = [
    (0.8, 0.1),
    (0.8, 0.2),
    (0.9, 0.1),
    (0.9, 0.2),
    (1.0, 0.1),
    (1.0, 0.2),
    (1.1, 0.1),
    (1.1, 0.2),
    (1.2, 0.1),
]

for timeout in test_examples:
    debug_timeout(timeout)

输出如下:

[DEBUG] Caught exception: HTTPSConnectionPool(host='httpbin.org', port=443): Read timed out. (read timeout=0.1)
[DEBUG] Caught exception: HTTPSConnectionPool(host='httpbin.org', port=443): Read timed out. (read timeout=0.2)
...

观察发现:

  • 哪怕是 (0.8, 0.1) 这种,连接阶段超时,报错也是 Read timed out
  • 明明连接都没成功,异常提示却是 read timeout

❗ 为什么连接超时也显示成“read timeout”?

这是 requests 的坑。

它底层用的是 urllib3,而 urllib3 会把某些连接错误和 TLS 握手失败统一包装成 ReadTimeoutError

也就是说:

  • 连接失败握手失败SSL 慢,有可能都显示为 Read timed out
  • 你以为是服务器响应慢,其实是你根本连不上。

✅ 如何精确判断是哪种超时?

推荐你这样写:

from requests.exceptions import ConnectTimeout, ReadTimeout

try:
    requests.get("https://httpbin.org/delay/8", timeout=(1, 0.5))
except ConnectTimeout:
    print("连接超时")
except ReadTimeout:
    print("读取超时")
except Exception as e:
    print("其他错误:", e)

用异常类去捕捉,比看字符串强一万倍


🧠 小结

类型含义注意事项
connect 超时TCP 建立连接超时域名解析失败、网络慢、TLS 握手慢也算在内
read 超时已连接,等待服务器响应超时常见于服务器处理太慢
单个 timeout表示连接+读取总时间限制不推荐,会混淆问题原因

🚀 建议实践

  • 扫描代理/测速时,推荐 timeout=(1, 1) 或 (1, 0.5);
  • 实时接口可设为 (2, 5)(3, 5)
  • 做异常处理要区分 ConnectTimeoutReadTimeout
  • 不建议用 timeout=5 这种形式,不好定位问题;

🔚 最后的话

这次实验让我意识到,“read timeout” 不一定真的是“读取超时”,有时候你连连接都没成功。

建议大家做网络爬虫、代理测速或接口监控时,不要只看报错信息的表面,要结合 timeout 参数逻辑和实际场景去理解


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值