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

如何在Python Requests重试前捕获首次请求失败并执行额外操作?

实现requests重试前的自定义操作

这个需求很常见,你说得没错——默认的urllib3 Retry机制只会在所有重试次数耗尽后才抛出异常,没法在每次重试前触发自定义逻辑。不过我们可以通过自定义Retry子类来解决这个问题,因为urllib3的Retry类提供了可重写的increment方法,这个方法会在每次准备重试前被调用,正好是我们插入操作的时机。

具体实现步骤

  1. 继承urllib3的Retry类,重写increment方法,在调用父类逻辑前执行你的额外操作;
  2. 在requests_retry_session函数中使用这个自定义的Retry类;
  3. 调整原有代码的异常捕获逻辑(现在每次重试前都会触发操作,最终失败才会进入except块)。

修改后的完整代码

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
import time

def do_something_more():
    # 执行告知用户API失败即将重试的操作
    print("I am doing something more... API请求失败,即将开始重试")

# 自定义Retry类,重写increment方法
class CustomRetry(Retry):
    def increment(self, method=None, url=None, response=None, error=None, _pool=None, _stacktrace=None):
        # 在重试前执行自定义操作
        do_something_more()
        # 调用父类的increment方法,继续原有的重试逻辑
        return super().increment(method, url, response, error, _pool, _stacktrace)

def requests_retry_session(
    retries=3,
    backoff_factor=0.3,
    status_forcelist=(500, 502, 504),
    session=None,
):
    session = session or requests.Session()
    # 使用自定义的CustomRetry替代默认Retry
    retry = CustomRetry(
        total=retries,
        read=retries,
        connect=retries,
        backoff_factor=backoff_factor,
        status_forcelist=status_forcelist,
    )
    adapter = HTTPAdapter(max_retries=retry)
    session.mount('http://', adapter)
    session.mount('https://', adapter)
    return session

# 使用示例
t0 = time.time()
try:
    response = requests_retry_session().get(
        'http://localhost:9999',
    )
except Exception as x:
    print('最终请求失败 :(', x.__class__.__name__)
else:
    print('请求最终成功', response.status_code)
finally:
    t1 = time.time()
    print('总耗时', t1 - t0, 'seconds')

关键说明

  • CustomRetry类重写的increment方法是urllib3重试逻辑的核心钩子,每次需要重试时都会被调用;
  • 如果你只想在首次失败后执行一次操作(而不是每次重试前都执行),可以在自定义Retry类里加个计数器,比如:
    class CustomRetry(Retry):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.retry_count = 0
    
        def increment(self, method=None, url=None, response=None, error=None, _pool=None, _stacktrace=None):
            if self.retry_count == 0:
                do_something_more()
            self.retry_count += 1
            return super().increment(method, url, response, error, _pool, _stacktrace)
    
  • 原代码里的do_somthing_more有拼写错误,已经修正为do_something_more。

内容的提问来源于stack exchange,提问作者rsnhah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:52:00