You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:33:48