requests.get() 默认自动跳转(allow_redirects=True)会导致爬虫失效,因反爬系统常利用301/302跳转至验证码页或空页,使你无法获取原始响应头和状态码,进而中断后续逻辑。
为什么 requests.get() 默认会自动跳转,反而导致爬虫失效
因为 requests 默认开启重定向追踪(allow_redirects=True),遇到 301、302 响应时会自动发起新请求,最终返回跳转后的页面内容。但很多反爬系统会利用这点:故意返回一个看似正常的跳转响应(比如跳到一个带验证码的中间页或空页面),而你根本收不到原始响应头和状态码,后续逻辑就断了。
常见表现是:你明明请求的是登录接口,却拿到一个首页 HTML;或者反复请求同一个 URL,response.url 却总在变;甚至触发风控后被塞进无限跳转循环(TooManyRedirects 异常)。
- 真实场景中,不少网站用
302+Set-Cookie+Location组合做前置校验,你需要手动提取跳转地址和 cookie,而不是让 requests 替你“一键到底” -
allow_redirects=False后,response.status_code保持为302,response.headers.get('Location')可直接拿到跳转目标 - 注意:禁用跳转后,
response.content是空的(HTTP 规范要求),别再拿它解析 HTML
如何安全地控制重定向——allow_redirects 的三种典型用法
这个参数不是非开即关,得看你要做什么。关键在于:你是否需要中间响应头?是否要自己构造下一次请求?是否要识别跳转意图?
- 查登录是否成功?→
allow_redirects=False,检查status_code == 302且Location是否含/dashboard或/user - 模拟浏览器完整访问流程?→
allow_redirects=True(默认),但必须加timeout和max_redirects=5防卡死 - 只取第一次跳转地址,不执行?→
allow_redirects=False,然后手动用requests.get(redirect_url, cookies=response.cookies)
示例:检测是否已登录
Python 3.14.3
微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。
resp = requests.get('https://example.com/profile', allow_redirects=False)
if resp.status_code == 302 and '/login' in resp.headers.get('Location', ''):
print("未登录,被重定向到登录页")
else:
print("已登录或响应正常")
Session 对象里 allow_redirects 怎么设才不冲突
Session 实例本身不保存 allow_redirects 设置,它只是个配置容器。真正起作用的是每次调用 .get()、.post() 时传入的参数——会覆盖 Session 的默认行为(即默认仍为 True)。
- 不要在
Session()初始化时传allow_redirects,它不接受这个参数 - 如果大部分请求都需要手动控制跳转,建议封装一个函数,统一处理
allow_redirects=False+ 异常捕获 + 头部检查 - 注意:
session.cookies在allow_redirects=False下仍会自动更新(只要响应带Set-Cookie),这点和跳转逻辑无关
容易忽略的副作用:重定向关闭后,response.history 就没了
response.history 是一个 tuple,记录所有自动跳转的 Response 对象。一旦设成 allow_redirects=False,它永远为空——这不是 bug,是设计使然。如果你依赖它来分析跳转链路(比如判断是否经过了风控中转页),那就必须自己记录。
- 简单方案:写个轻量 wrapper,每次请求前存当前 URL,收到
3xx就追加到列表 - 复杂点的:用
requests.adapters.HTTPAdapter自定义 redirect 处理,但多数爬虫没必要这么重 - 另一个坑:
response.is_redirect属性在allow_redirects=False下依然有效,可用来快速判断响应类型,别误以为它依赖 history
重定向控制的本质,不是“要不要跳”,而是“谁来决定下一步”。把选择权拿回来,比让 requests 替你兜底更可控——尤其当目标网站的跳转逻辑本身就是反爬手段时。