aiohttp默认重定向可能卡住或无限跳转,因其max_redirects仅限次数不检测URL环路;需结合手动路径跟踪与合理设置max_redirects=3等值来防范。
为什么
默认重定向会卡住或无限跳转
默认情况下
允许最多 10 次重定向(
),但这个限制只对「连续 301/302 响应」生效,且不校验跳转目标是否重复。如果服务端返回的
头在两个 URL 之间来回跳(比如 A→B→A→B…),
不会检测环路,只会耗尽次数后抛出
或卡在连接上(尤其配合
时)。
常见诱因包括:反爬中间件误配、OAuth 回调地址未正确设置、测试环境 DNS 解析异常、或服务端自身逻辑缺陷。
如何用
安全控制重定向次数
显式设置
是最直接的兜底手段,但它只是“数量限制”,不能替代环路检测。关键点在于:这个参数必须传给
构造函数,而不是单次
调用 —— 后者会忽略该参数。
:完全禁用重定向,所有 3xx 响应都原样返回(适合调试跳转链)
:多数业务场景够用,避免深层嵌套又留出合理容错
:适用于已知只跳一次的登录跳转或短链服务
示例:
立即学习
“
Python免费学习笔记(深入)
”;
Python 3.14.3
微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。
下载
真正防死循环得靠手动跟踪跳转路径
只能防“次数爆炸”,防不了“URL 循环”。要彻底解决,需在每次重定向后记录
,并检查是否出现重复。注意:
是最终解析后的绝对 URL(含协议和 host),比读
头更可靠。
用
存已访问的
,每次跳转前查重
跳转后立即
若需兼容重定向中间状态,可搭配
手动处理 3xx 响应
小技巧:把跳转历史存进
(
自动维护的
),它包含所有中间响应对象,可用于分析跳转链条。
其他容易被忽略的配置联动点
重定向行为不是孤立的,以下配置会间接影响死循环表现:
:重定向过程中每个请求都受 timeout 约束,但默认
的
可能掩盖慢跳转问题;建议显式设
和
:设为
时,3xx 响应不会抛异常,但后续跳转失败才触发;设为
可早发现非 2xx 状态
:跨域重定向时 cookie 默认不携带,若跳转依赖会话态,需确认
是否启用及策略
:设为
可避免系统代理(如 HTTP_PROXY)意外引入额外跳转
环路检测逻辑本身没有标准库支持,得自己写;而
只是第一道防线,真正在生产环境跑异步
爬虫
,跳转路径去重比调大这个数字重要得多。
aiohttpaiohttp.ClientSessionmax_redirects=10Locationaiohttpaiohttp.ClientResponseErrorraise_for_status=Truemax_redirectsmax_redirectsClientSessionsession.get()max_redirects=0max_redirects=3max_redirects=1import aiohttp
✅ 正确:传给 ClientSession
async with aiohttp.ClientSession(max_redirects=3) as session:
async with session.get("https://www.php.cn/link/b05edd78c294dcf6d960190bf5bde635") as resp:
print(resp.status)
❌ 错误:这个 max_redirects 不起作用
async with session.get("https://...", max_redirects=3) as resp:
max_redirectsresp.urlresp.urlLocationsetstr(resp.url)if str(resp.url) in seen_urls: raise RuntimeError("Redirect loop detected")allow_redirects=Falseresp.historyaiohttptupletimeoutaiohttpClientTimeout(total=5*60)connectsock_readraise_for_statusTrueFalsecookiessession.cookie_jartrust_envFalsemax_redirects