aiohttp默认重定向可能卡住或无限跳转,因其max_redirects仅限次数不检测URL环路;需结合手动路径跟踪与合理设置max_redirects=3等值来防范。

为什么 aiohttp 默认重定向会卡住或无限跳转
默认情况下 aiohttp.ClientSession 允许最多 10 次重定向(max_redirects=10),但这个限制只对「连续 301/302 响应」生效,且不校验跳转目标是否重复。如果服务端返回的 Location 头在两个 URL 之间来回跳(比如 A→B→A→B…),aiohttp 不会检测环路,只会耗尽次数后抛出 aiohttp.ClientResponseError 或卡在连接上(尤其配合 raise_for_status=True 时)。
常见诱因包括:反爬中间件误配、OAuth 回调地址未正确设置、测试环境 DNS 解析异常、或服务端自身逻辑缺陷。
如何用 max_redirects 安全控制重定向次数
显式设置 max_redirects 是最直接的兜底手段,但它只是“数量限制”,不能替代环路检测。关键点在于:这个参数必须传给 ClientSession 构造函数,而不是单次 session.get() 调用 —— 后者会忽略该参数。
-
max_redirects=0:完全禁用重定向,所有 3xx 响应都原样返回(适合调试跳转链) -
max_redirects=3:多数业务场景够用,避免深层嵌套又留出合理容错 -
max_redirects=1:适用于已知只跳一次的登录跳转或短链服务
示例:
立即学习“Python免费学习笔记(深入)”;
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
import aiohttp
<h1>✅ 正确:传给 ClientSession</h1><p>async with aiohttp.ClientSession(max_redirects=3) as session:
async with session.get("<a href="https://www.php.cn/link/b05edd78c294dcf6d960190bf5bde635">https://www.php.cn/link/b05edd78c294dcf6d960190bf5bde635</a>") as resp:
print(resp.status)</p><h1>❌ 错误:这个 max_redirects 不起作用</h1><h1>async with session.get("https://...", max_redirects=3) as resp:</h1><p>真正防死循环得靠手动跟踪跳转路径
max_redirects 只能防“次数爆炸”,防不了“URL 循环”。要彻底解决,需在每次重定向后记录 resp.url,并检查是否出现重复。注意:resp.url 是最终解析后的绝对 URL(含协议和 host),比读 Location 头更可靠。
- 用
set存已访问的str(resp.url),每次跳转前查重 - 跳转后立即
if str(resp.url) in seen_urls: raise RuntimeError("Redirect loop detected") - 若需兼容重定向中间状态,可搭配
allow_redirects=False手动处理 3xx 响应
小技巧:把跳转历史存进 resp.history(aiohttp 自动维护的 tuple),它包含所有中间响应对象,可用于分析跳转链条。
其他容易被忽略的配置联动点
重定向行为不是孤立的,以下配置会间接影响死循环表现:
-
timeout:重定向过程中每个请求都受 timeout 约束,但默认aiohttp的ClientTimeout(total=5*60)可能掩盖慢跳转问题;建议显式设connect和sock_read -
raise_for_status:设为True时,3xx 响应不会抛异常,但后续跳转失败才触发;设为False可早发现非 2xx 状态 -
cookies:跨域重定向时 cookie 默认不携带,若跳转依赖会话态,需确认session.cookie_jar是否启用及策略 -
trust_env:设为False可避免系统代理(如 HTTP_PROXY)意外引入额外跳转
环路检测逻辑本身没有标准库支持,得自己写;而 max_redirects 只是第一道防线,真正在生产环境跑异步爬虫,跳转路径去重比调大这个数字重要得多。

















