当前位置: 首页 > 图灵资讯 > 行业资讯> 如何在Python 3.12中编写健壮的脚本来处理不稳定的网络连接请求?

如何在Python 3.12中编写健壮的脚本来处理不稳定的网络连接请求?

来源:图灵python
时间: 2026-07-21 17:05:17
requests.get() 默认情况下,当DNS失败、连接加班等直接抛出Conectioneror或timeout异常时,程序会崩溃,因为它没有被try/except捕获;建议使用retry策略实现带回避和上限的自动重试,而不是错误。

为什么 requests.get() 直接报错就崩溃?

因为默认情况 requests.get() 遇到 DNS 如果连接超时或远程断开,将直接抛出 requests.exceptions.ConnectionErrorrequests.exceptions.Timeout,没有捕获就退出。这不是“异常”,而是网络常态——你必须把它当作预期的分支,而不是错误。

实操建议:

立即学习“Python免费学习笔记(深入);

  • 永远用 try/except 包裹单个请求,至少覆盖 requests.exceptions.RequestException(它是所有 requests 父类异常)
  • 别只 catch Timeout:DNS 解析失败(ConnectionError)、SSL 验证失败(SSLError)、空响应(ChunkedEncodingError)都得兜住
  • Python 3.12 对 SSL 上下文比较严格,有些自签或过期证书会触发 ssl.SSLCertVerificationError,需要显式关闭验证(仅测试环境)或配置 verify=False
脚本如何在不卡死的情况下自动重试?

硬写 while True: + time.sleep() 容易失控:无限重试,指数退出,没有设定最大尝试次数。建议使用 urllib3.util.retry.Retry(requests 内置),它和 Python 3.12 兼容性和支持状态码重试。

实操建议:

立即学习“Python免费学习笔记(深入);

  • 构造 Retry 实例时,明确指定 connect(连接失败)、read(读取超时)、status(如 502/503三种重试条件
  • backoff_factor=1 退出启动指数:第一 1 次重试等 1s,第 2 次等 2s,第 3 次等 四s...避免雪崩
  • 必须设 total=3 或类似上限,否则永久性故障(如域名不存在)将永远存在 retry
  • 示例:
    from requests.adapters import HTTPAdapter<br>from urllib3.util.retry import Retry<br><br>retry_strategy = Retry(<br>    total=3,<br>    backoff_factor=1,<br>    status_forcelist=[429, 502, 503, 504],<br>    allowed_methods=["HEAD", "GET", "OPTIONS"]<br>)<br>adapter = HTTPAdapter(max_retries=retry_strategy)
如何判断请求是“真正失败”还是“可恢复”?

HTTP 状态码不是唯一的依据。例如,返回 200 但 body 是空、JSON 分析失败和字段缺失不会触发这种业务失败 requests 重试机制,但对你的逻辑来说是失败。

Python 3.14.2

Python 3.14.2是Python编程语言于2025年12月5日发布的稳定版本,属于3.14系列的第二次维护更新。该版本包含18个修复项目,重点解决多过程、数据和正则表达模块的回归问题,修复CVE-2025-12084等安全漏洞。这个版本标志着Python发展的一个重要里程碑,即自由线程模式(删除GIL)正式得到官方支持。

下载

实操建议:

立即学习“Python免费学习笔记(深入);

  • 检查 r.status_code 之后,立即进行验证 r.content 长度(len(r.content) > 0)和 r.headers.get("content-length") 是否匹配
  • r.json() 前先 if "application/json" in r.headers.get("content-type", ""),避免非 JSON 响应触发 JSONDecodeError
  • 防御性提取关键字段:data.get("items", []) 而不是 data["items"],防止 KeyError 中断流程
  • 记录原始响应头和前面 200 字节 body(r.content[:200])到日志,方便事后区分是服务问题还是逻辑问题
Python 3.12 的 asyncio + httpx 组合应该注意什么?

若采用异步并发请求,httpx.AsyncClientrequests 更适合,但 Python 3.12 的 asyncio 事件的默认循环变化(Windows 上改用 asyncio.WindowsSelectorEventLoopPolicy)可能会导致兼容性问题。

实操建议:

立即学习“Python免费学习笔记(深入);

  • 启动前加 asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())(仅 Windows),否则可能报 RuntimeError: Event loop is closed
  • 别在 async with httpx.AsyncClient() 外调用 await client.get(...):client 必须在 async context manager 内使用
  • 不能使用异步重试 time.sleep(),必须用 await asyncio.sleep(1)
  • 盲目设置并发数量:超过目标服务器的承载能力会触发 相反,429降低了成功率;建议从 concurrency=5 开始压测

真正困难的不是添加 try 或设 retry,相反,区分哪些失败应该重新测试,哪些应该跳过,哪些应该警告——这取决于你 API 库能不为你决定文档和历史错误日志的观察。