非常游戏网
如何解决Python爬虫请求频繁被重定向的问题_设置allow_redirects参数

如何解决Python爬虫请求频繁被重定向的问题_设置allow_redirects参数

2026-05-29日常编程275054

requests.get() 默认自动跳转(allow_redirects=True)会导致爬虫失效,因反爬系统常利用301/302跳转至验证码页或空页,使你无法获取原始响应头和状态码,进而中断后续逻辑。

为什么 requests.get() 默认会自动跳转,反而导致爬虫失效

因为 requests 默认开启重定向追踪(allow_redirects=True),遇到 301302 响应时会自动发起新请求,最终返回跳转后的页面内容。但很多反爬系统会利用这点:故意返回一个看似正常的跳转响应(比如跳到一个带验证码的中间页或空页面),而你根本收不到原始响应头和状态码,后续逻辑就断了。

常见表现是:你明明请求的是登录接口,却拿到一个首页 HTML;或者反复请求同一个 URL,response.url 却总在变;甚至触发风控后被塞进无限跳转循环(TooManyRedirects 异常)。

  • 真实场景中,不少网站用 302 + Set-Cookie + Location 组合做前置校验,你需要手动提取跳转地址和 cookie,而不是让 requests 替你“一键到底”
  • allow_redirects=False 后,response.status_code 保持为 302response.headers.get('Location') 可直接拿到跳转目标
  • 注意:禁用跳转后,response.content 是空的(HTTP 规范要求),别再拿它解析 HTML

如何安全地控制重定向——allow_redirects 的三种典型用法

这个参数不是非开即关,得看你要做什么。关键在于:你是否需要中间响应头?是否要自己构造下一次请求?是否要识别跳转意图?

  • 查登录是否成功?→ allow_redirects=False,检查 status_code == 302Location 是否含 /dashboard/user
  • 模拟浏览器完整访问流程?→ allow_redirects=True(默认),但必须加 timeoutmax_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.cookiesallow_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 替你兜底更可控——尤其当目标网站的跳转逻辑本身就是反爬手段时。