超时重试:设置请求超时与自动重试机制(Retry策略),爬虫优雅降级之道:超时重试机制的深度实践与源码解析
写爬虫的人,大概都经历过这样的深夜:脚本跑了三个小时,眼看就要收网了,结果因为一个请求超时,整个程序崩了。第二天上班一看日志,凌晨两点十分,requests.exceptions.Timeout,干干净净。
那一刻你才知道,优雅地处理超时和失败,比写出花哨的解析逻辑重要一万倍。
所以这篇文章,不是教你写爬虫,而是教你在爬虫里体面地活着。我们会从最基础的超时设置讲起,一路深入到自适应重试、熔断降级、异步重试池,最后给出可以直接复制到生产环境的完整代码。字数可能有点多,但每一行都是实战踩过的坑。
如果你希望这篇文章“不像AI写的”,那我的风格就是——不讲废话,不回避坑点,代码给出注释,遇到坑直接说。
目录
第一章:超时——最容易忽略的保命符
1.1 没有超时的请求有多危险
1.2 timeout 参数的两种写法
1.3 使用 asyncio + aiohttp 的超时设置
1.4 你以为超时只抛一个异常就完了?不,它有两个坑
第二章:重试——给服务器一次改过自新的机会
2.1 重试不是无脑循环
2.2 使用 urllib3 的重试(最底层)
2.3 使用 tenacity 库——重试界的瑞士军刀
2.4 异步重试:aiohttp + tenacity
第三章:重试的高级策略——别让你的爬虫变成DDoS工具
3.1 熔断器模式(Circuit Breaker)
3.2 重试预算(Retry Budget)
3.3 区分可重试异常和不可重试异常
第四章:实战——完整的企业级爬虫重试封装
4.1 需求
4.2 同步版本(完整代码)
4.3 异步版本(核心代码)
第一章:超时——最容易忽略的保命符
1.1 没有超时的请求有多危险
很多人写爬虫是这样写的:
python
import requests response = requests.get('https://httpbin.org/delay/10')这段代码的问题在哪?它永远在等。如果对方服务器故意不响应,或者网络断了,你的线程会一直卡在那里。爬虫最怕的不是报错,而是不报错地死等。
正确的做法:永远设置超时。
python
response = requests.get('https://htt