如何为requests库的重试请求设置时间间隔?求更优方案
更优雅的 Requests 重试方案:自定义退避策略
嘿,你的手动循环重试思路没问题,但其实可以借助 Requests 底层的 urllib3 重试机制,实现更简洁、可复用的方案,还能轻松控制重试间隔!
核心思路:用 urllib3.Retry 定制重试规则
Requests 的 HTTPAdapter 默认支持重试,但默认没有间隔。我们可以通过 urllib3.util.retry.Retry 类来配置重试次数、触发重试的场景,重点是通过 backoff_factor 参数实现指数退避,甚至自定义线性间隔。
代码实现(对齐你的原有逻辑)
你原来的代码是尝试4次请求(1次初始 + 3次重试),如果想沿用你那种重试次数*2+1的线性间隔,或者用更推荐的指数退避,代码可以这么写:
import logging import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry def create_retry_session(retries=3, backoff_factor=2, status_forcelist=(429, 500, 502, 503, 504)): session = requests.Session() # 初始化重试策略 retry_strategy = Retry( total=retries, # 总重试次数(初始请求不算在内,对应你原来的3次重试) read=retries, connect=retries, backoff_factor=backoff_factor, # 退避因子,默认是指数退避:间隔 = backoff_factor * (2 ** (重试次数-1)) status_forcelist=status_forcelist, # 触发重试的HTTP状态码 allowed_methods=["GET"] # 只对GET请求重试(POST这类非幂等请求谨慎开启) ) # 如果你要完全自定义间隔(比如你原来的 retry*2+1),可以重写get_backoff_time方法 def custom_backoff(self, retry_number): return retry_number * 2 + 1 retry_strategy.get_backoff_time = custom_backoff.__get__(retry_strategy, Retry) # 将策略挂载到session的适配器上 adapter = HTTPAdapter(max_retries=retry_strategy) session.mount("http://", adapter) session.mount("https://", adapter) return session # 使用示例 target_url = "你的目标URL" session = create_retry_session(retries=3) # 对应4次请求尝试(1初始+3重试) try: logging.warning('[fetch] start fetching url=%s' % target_url) resp = session.get(target_url, timeout=3) resp.raise_for_status() # 触发HTTP状态码异常(比如4xx/5xx) data = resp.text logging.warning('[fetch] fetch success') except Exception as e: logging.warning('[fetch] failed after all retries: %s' % e) data = None # 按需处理失败场景
为什么这比手动循环更好?
- 复用性强:封装成session后,所有请求都能自动套用重试规则,不用每次写重复的循环
- 服务端友好:默认的指数退避是业界最佳实践,避免短时间内大量请求压垮目标服务器
- 异常处理更精准:默认会处理连接错误、读取超时、指定HTTP状态码,比泛捕Exception更可靠
- 扩展性高:可以轻松调整重试次数、触发条件、间隔规则,甚至自定义退避逻辑
小提示
你原来的代码里if data is False的判断有点问题——resp.text永远不会是False,请求失败时会直接抛出异常。建议用resp.raise_for_status()来主动触发HTTP状态码异常,统一用try-except处理所有失败场景。
内容的提问来源于stack exchange,提问作者daisy
相关产品推荐
相关产品推荐

