Python网络请求重试的正确姿势是什么

来源:程序开发作者:阿亮头衔:草根站长
导读:本期聚焦于小伙伴创作的《Python网络请求重试的正确姿势是什么》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Python网络请求重试的正确姿势是什么》有用,将其分享出去将是对创作者最好的鼓励。

在Python开发中,网络请求是非常常见的操作,无论是调用第三方API、爬取网页数据还是和内部服务交互,都可能遇到请求失败的情况。合理的重试机制可以有效降低这类临时故障带来的影响,提升程序的可用性。

Python网络请求重试的正确姿势是什么

为什么不能直接用循环做重试

很多初学者实现重试时,会直接写一个for循环多次发送请求,这种方式的缺陷非常明显:

  • 没有区分错误类型,比如请求参数错误导致的400状态码,重试多少次都不会成功,反而会浪费资源
  • 没有设置重试间隔,连续快速重试可能会给服务端造成压力,甚至触发服务端的限流策略
  • 没有限制最大重试次数,一旦遇到持续故障,程序会陷入无限重试的状态
  • 没有处理重试过程中的异常累积,多次失败后无法正确抛出最终的异常信息

基于urllib3的Retry实现重试

requests库底层依赖urllib3,urllib3内置了Retry类,可以很方便地实现精细化的重试策略。我们可以通过配置Retry对象,指定重试的条件、次数、间隔等参数,再将其挂载到requests的适配器中。

基础重试配置示例

以下是一个针对GET请求设置重试的完整示例:

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

# 创建重试策略对象
retry_strategy = Retry(
    total=3,  # 最大重试次数
    backoff_factor=1,  # 重试间隔的基数,重试间隔为backoff_factor * (2 ** (重试次数-1))
    status_forcelist=[429, 500, 502, 503, 504],  # 需要触发重试的HTTP状态码
    allowed_methods=["GET"]  # 允许重试的请求方法,默认只有GET
)

# 创建HTTP适配器并挂载重试策略
adapter = HTTPAdapter(max_retries=retry_strategy)

# 创建session对象并挂载适配器
http = requests.Session()
http.mount("https://", adapter)
http.mount("http://", adapter)

try:
    # 发送请求
    response = http.get("http://ipipp.com/api/test", timeout=5)
    print(f"请求成功,状态码:{response.status_code}")
    print(f"响应内容:{response.text}")
except Exception as e:
    print(f"请求最终失败,错误信息:{e}")

参数说明

上面示例中Retry的核心参数含义如下:

参数名含义
total最大重试次数,包括第一次请求,设置为3表示最多发送3次请求
backoff_factor重试间隔的基数,实际重试间隔为backoff_factor * (2 ** (重试次数-1)),比如backoff_factor=1时,第一次重试间隔1秒,第二次2秒,第三次4秒
status_forcelist触发重试的HTTP状态码列表,只有返回这些状态码时才会重试,避免对参数错误等永久性错误重试
allowed_methods允许重试的请求方法,默认只有GET,POST等修改数据的请求默认不允许重试,避免重复提交数据

针对POST请求的重试注意事项

POST请求通常用于提交数据,默认情况下urllib3的重试策略不会对其重试,因为重复发送POST请求可能会导致重复创建数据、重复扣款等问题。如果确实需要为POST请求添加重试,需要满足两个条件:

  • 接口是幂等的,也就是多次调用产生的效果和执行一次相同
  • allowed_methods参数中显式添加POST方法

示例配置如下:

retry_strategy = Retry(
    total=2,
    backoff_factor=0.5,
    status_forcelist=[500, 502, 503, 504],
    allowed_methods=["GET", "POST"]  # 显式允许POST方法重试
)

自定义异常重试逻辑

除了HTTP状态码触发重试,还可以针对特定的异常类型设置重试,比如连接超时、读取超时等网络异常。可以通过Retryraise_on_status和自定义异常判断逻辑实现:

from urllib3.exceptions import ConnectTimeoutError, ReadTimeoutError

def is_retryable_exception(exception):
    # 判断异常是否属于可重试的类型
    return isinstance(exception, (ConnectTimeoutError, ReadTimeoutError))

retry_strategy = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[500, 502, 503, 504],
    # 自定义重试判断逻辑
    retry=is_retryable_exception
)

常见误区提醒

不要对所有错误都开启重试,比如4xx状态码中的400、401、403等,通常是请求本身有问题,重试没有意义。
重试间隔不要设置得太短,避免对服务端造成不必要的压力,同时降低触发限流的概率。
如果请求涉及敏感操作,比如支付、数据删除,尽量不要开启重试,或者做好幂等性校验。

通过urllib3的Retry类结合requests的适配器机制,我们可以很灵活地实现符合业务需求的网络请求重试策略,避免简单循环重试带来的各种问题,让程序的网络请求部分更加健壮可靠。

Python网络请求重试机制requestsurllib3修改时间:2026-07-16 06:54:29

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。