requests.get() 默认情况下,当DNS失败、连接加班等直接抛出Conectioneror或timeout异常时,程序会崩溃,因为它没有被try/except捕获;建议使用retry策略实现带回避和上限的自动重试,而不是错误。为什么 requests.get() 直接报错就崩溃?
因为默认情况 requests.get() 遇到 DNS 如果连接超时或远程断开,将直接抛出 requests.exceptions.ConnectionError 或 requests.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])到日志,方便事后区分是服务问题还是逻辑问题
若采用异步并发请求,httpx.AsyncClient 比 requests 更适合,但 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 库能不为你决定文档和历史错误日志的观察。