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

如何使用Python backoff库实现连续5次405状态码后的重试控制、长休眠及错误打印?

解决连续5次405状态码后触发长休眠的问题

你的核心问题在于原代码里的giveup函数逻辑——只要单次收到405就直接返回True,导致backoff库立刻终止重试,完全没机会累积到5次连续错误。要实现需求,我们需要跟踪连续405的次数,只有当次数达标时才执行长休眠和提示,同时让backoff继续重试直到触发这个条件。

方案一:利用backoff库的钩子+闭包实现

这个方案保留backoff库的退避策略优势,用闭包来安全跟踪连续错误次数(避免全局变量),配合on_backoff钩子在每次重试前检查状态:

import time
import backoff
import requests

def track_consecutive_405():
    # 闭包保存连续405的计数器
    consecutive_405 = 0
    def backoff_handler(details):
        nonlocal consecutive_405
        # 检查当前异常是否是HTTPError且状态码为405
        if isinstance(details['exception'], requests.exceptions.HTTPError):
            response = details['exception'].response
            if response and response.status_code == 405:
                consecutive_405 += 1
                print(f"连续第{consecutive_405}次收到405状态码")
                # 达到5次连续错误时执行长休眠
                if consecutive_405 >= 5:
                    print("发生405状态错误")
                    time.sleep(60000)
                    # 重置计数器,继续后续重试
                    consecutive_405 = 0
            else:
                # 非405的错误,重置计数器
                consecutive_405 = 0
        else:
            # 其他请求异常(超时、连接错误等),重置计数器
            consecutive_405 = 0
    return backoff_handler

@backoff.on_exception(
    backoff.expo,  # 可根据需求替换为constant等其他退避策略
    requests.exceptions.HTTPError,  # 精确捕获raise_for_status抛出的HTTP错误
    max_tries=None,  # 不限制总重试次数,由我们的计数器逻辑控制
    on_backoff=track_consecutive_405()  # 绑定自定义的重试钩子
)
def publish(url):
    r = requests.post(url, timeout=10)
    r.raise_for_status()

publish("https://www.google.se/")

方案二:自定义循环+计数器(无需backoff库)

如果你更偏爱完全可控的逻辑,可以参考你之前的计数器思路,优化后实现需求:

import requests
import time
from backoff import expo  # 可选:复用backoff的退避策略计算

def publish(url):
    consecutive_405 = 0
    while True:
        try:
            r = requests.post(url, timeout=10)
            if r.status_code == 405:
                consecutive_405 += 1
                print(f"连续第{consecutive_405}次收到405状态码")
                if consecutive_405 >= 5:
                    print("发生405状态错误")
                    time.sleep(60000)
                    consecutive_405 = 0
                # 用expo策略计算重试间隔,也可以替换为固定时间
                time.sleep(expo()(consecutive_405))
            else:
                r.raise_for_status()  # 其他HTTP错误抛出异常
                print("请求成功")
                consecutive_405 = 0
                break  # 成功后退出循环,可根据需求调整
        except requests.exceptions.RequestException as e:
            print(f"请求异常: {str(e)}")
            consecutive_405 = 0  # 非405异常重置计数器
            time.sleep(5)  # 短间隔后重试

publish("https://www.google.se/")

关键逻辑说明

  1. 放弃原giveup的405判断:原代码中giveup一碰到405就终止重试,这和你需要累积5次的需求完全冲突,必须移除这个判断。
  2. 连续错误计数:用闭包(方案一)或局部变量(方案二)跟踪连续405的次数,避免全局变量的副作用。
  3. 阈值触发动作:当计数达到5时,执行长休眠并打印提示,之后可选择重置计数器继续重试,或根据业务需求终止流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 09:12:29