Python中HTTP请求需掌握超时控制、自动重试和Session管理:timeout设为(connect, read)元组;用Retry+Session实现指数退避重试;Session自动处理Cookie、复用连接并统一配置。
Python 中用 requests 发 HTTP 请求,光会 get() 和 post() 远远不够。真实项目里常遇到网络抖动、服务暂时不可用、需要保持登录态等情况,这时候必须掌握超时控制、自动重试和 Session 管理。
不设超时是常见隐患:DNS 解析卡住、服务器没响应、网络中断,都可能让程序卡死几十秒甚至更久。requests 的 timeout 参数必须显式指定,它接受一个元组 (connect_timeout, read_timeout):
示例:requests.get(url, timeout=(3, 10)) 表示 3 秒连不上就放弃,连上后最多等 10 秒收完数据。
网络瞬断或服务临时 502/503 很常见。requests 本身不带重试逻辑,需借助 urllib3 的 Retry 类或第三方库(如 tenacity)。推荐用内置方式组合 Session + Retry:
Retry 实例,指定最大重试次数、退避因子(指数退避)、要重试的状态码(如 429、500、502、503、504)关键代码片段:
from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry session = requests.Session() retry_strategy = Retry( total=3, status_forcelist=(429, 500, 502, 503, 504), backoff_factor=1 ) adapter = HTTPAdapter(max_retries=retry_strategy) session.mount("http://", adapter) session.mount("https://", adapter)
单次 requests.get() 是“无状态”的:每次新建 TCP 连接、不保存 Cookie、不复用连接。而 Session 对象能解决这三件事:
注意:Session 不是线程安全的,多线程中应为每个线程创建独立实例,或用 threading.local() 隔离。
把上面三部分整合,就能写出稳定可用的请求封装。例如封装一个通用请求函数:
Timeout)、连接失败(ConnectionError)、HTTP 异常(HTTPError),其他按需捕获这样既避免了重复造轮子,又确保每次请求都具备容错能力与上下文一致性。