如何针对特定异常及5xx状态码对Python requests请求进行重试?
问题根因
你当前的代码将try...except包裹了完整请求逻辑,触发Timeout异常后会直接退出try块,没有重试入口,因此程序会直接终止。
修改方案
新增外层无限循环作为统一重试入口,调整异常捕获后的逻辑即可实现需求,修改后完整代码如下:
import time import requests from bs4 import BeautifulSoup from requests import ( RequestException, Timeout ) def do_request(): # 外层无限循环作为统一重试入口 while True: try: # 部分场景下我会使用自定义代理,写法如下 # requests.get("https://www.bbc.com/", timeout=0.1, proxies={'https': 'xxx.xxxx.xxx.xx'}) # 5xx状态码重试逻辑保留 while (response := requests.get("https://www.bbc.com/", timeout=0.1)).status_code >= 500: print("sleeping") time.sleep(20) if response.status_code not in (200, 404): response.raise_for_status() print("Successful requests!") soup = BeautifulSoup(response.text, 'html.parser') for link in soup.find_all("a", {"class": "media__link"}): yield link.get('href') # 成功完成所有逻辑后退出外层循环,终止重试 break except Timeout as err: print(f"Retry due to timed out: {err}") # 触发下一轮循环重试 continue except RequestException as err: raise RequestException("Unexpected request error") # ----------------------------------------------------# if __name__ == '__main__': for found_links in do_request(): print(found_links)
核心修改点
- 新增外层无限循环,覆盖5xx状态码、Timeout异常两类可重试场景
- Timeout异常捕获后仅打印日志,通过
continue触发外层循环重新发起请求 - 请求成功并完成链接解析返回后,通过
break主动退出外层循环 - 不可重试的异常(非200/404/5xx状态码、其他请求异常)保留原有抛出逻辑,符合需求要求
内容的提问来源于stack exchange,提问作者PythonNewbie
相关产品推荐
相关产品推荐

