合理设置超时、区分连接与读取阶段、结合重试机制和异步并发优化,可有效应对Python中requests库的超时问题。1. 始终设置timeout参数,如timeout=(3,5);2. 连接超时设短、读取超时设长以适应API特性;3. 使用Retry类配置重试策略,提升网络波动下的成功率;4. 批量请求采用aiohttp异步并发,控制总超时与并发数,提高整体效率。
Python中使用requests库发起网络请求时,经常会遇到TimeoutError或requests.exceptions.Timeout异常。这通常是因为服务器响应过慢或网络不稳定导致连接未能在规定时间内完成。合理处理和优化超时问题,不仅能提升程序稳定性,还能避免资源浪费。
不设置超时可能导致程序无限等待。建议始终为请求指定超时时间:
timeout参数控制连接和读取超时import requeststry: response = requests.get( "https://www./link/85c19375f0c12c6793bf66b4e2666dc4", timeout=(3, 5) # 连接3秒,读取5秒 ) print(response.status_code) except requests.exceptions.Timeout: print("请求超时,请检查网络或目标服务状态")
将超时拆分为两个阶段更精细地控制:
例如,远程API通常连接快但处理慢,可设较短连接超时、较长读取超时。
临时网络抖动可能导致超时,引入重试可提高成功率:
urllib3的Retry类配合requests.adapters.HTTPAdapter
from requests.adapters import HTTPAdapter from urllib3.util.retry import Retrysession = requests.Session() retries = Retry( total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504], allowed_methods=["GET", "POST"] ) adapter = HTTPAdapter(max_retries=retries) session.mount("http://", adapter) session.mount("https://", adapter)
try: resp = session.get("https://www./link/46b315dd44d174daf5617e22b3ac94ca", timeout=(3, 10)) except requests.exceptions.Timeout: print("最终请求失败:超时")
对于批量请求,同步方式容易因个别超时拖慢整体速度。可改用异步方案:
aiohttp + asyncio实现并发请求
import aiohttp import asyncioasync def fetch(session, url): try: async with session.get(url, timeout=10) as resp: return await resp.text() except asyncio.TimeoutError: print(f"超时: {url}") return None
async def main(): urls = ["https://www./link/ef246753a70fce661e16668898810624"] * 5 connector = aiohttp.TCPConnector(limit=10) timeout = aiohttp.ClientTimeout(total=15)
async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session: tasks =[fetch(session, url) for url in urls] return await asyncio.gather(*tasks)
results = asyncio.run(main())
基本上就这些方法。关键是根据实际场景选择合适的超时策略,结合重试与并发,才能有效应对网络不确定性。