requests.get()默认自动跟随重定向,response.url返回最终真实地址;若需获取跳转链路,须设allow_redirects=False并手动解析Location头或HTML中的meta/JS跳转,同时限制最大跳转次数、归一化URL防环路。

直接用 requests.get() 默认会自动跟随重定向,拿到的 response.url 就是最终真实地址——但前提是没关 allow_redirects,且目标没做 JavaScript 跳转或 meta refresh。
为什么 requests.get() 返回的 url 不是短链接本身?
因为 requests 默认开启重定向追踪(allow_redirects=True),遇到 301 / 302 响应时会自动发起后续请求,直到状态码不是重定向类(如 200)才停止。最终 response.url 是最后一次响应的 URL,也就是跳转终点。
- 如果你需要原始短链接的跳转链路(比如查 301 → 302 → 200),得手动禁用自动跳转:
allow_redirects=False,再自己处理response.headers.get("Location") - 注意:某些短链服务(如
t.co、bit.ly)会在响应头中返回Location,但也有些会返回200+ HTML 内含<meta http-equiv="refresh">或内联 JS,这种requests无法自动识别 - 超时和 User-Agent 缺失容易被封,建议加
timeout=5和通用headers={"User-Agent": "Mozilla/5.0..."}
如何安全获取完整跳转路径(含中间跳转)?
用循环 + allow_redirects=False 手动跟进,每次检查 response.status_code 是否为 3xx,并读取 Location 头。关键点在于避免无限跳转和环路。
- 设置最大跳转次数(如
max_redirects=5),防止死循环 - 记录已访问的 URL(用
set存 normalized URL,比如去掉 fragment、统一 scheme),发现重复立即中断 -
Location可能是相对路径,需用urllib.parse.urljoin(current_url, location)拼接 - 示例片段:
url = short_url<br>visited = set()<br>for _ in range(5):<br> if url in visited:<br> break<br> visited.add(url)<br> r = requests.get(url, allow_redirects=False, timeout=5, headers=headers)<br> if r.status_code in (301, 302, 303, 307, 308):<br> url = urljoin(url, r.headers.get("Location", ""))<br> else:<br> break
遇到 JS 跳转或 meta refresh 怎么办?
requests 不执行 JS,也不解析 HTML 自动跳转,这类情况必须上 BeautifulSoup 或 lxml 提取跳转信息,或者换 selenium / playwright 渲染页面。
立即学习“Python免费学习笔记(深入)”;
- 先检查响应内容是否含
<meta http-equiv="refresh" content="0;url=...>,用BeautifulSoup(response.text, "html.parser")提取content属性里的 URL - JS 跳转常见形式:
window.location.href = "...";或document.location = "...";,可用正则粗略匹配:re.search(r'location\s*[\.\=]\s*[\'"]([^\'"]+)[\'"]', text) - 不推荐无脑上浏览器自动化——性能差、资源重;优先尝试解析 HTML + 正则,仅当结构复杂或混淆严重时再考虑
playwright.sync_playwright().start()启动无头浏览器 - 注意:部分站点会根据 UA 或 IP 返回不同内容,JS 跳转可能只对浏览器 UA 生效,此时
requests拿到的 HTML 里根本没那段 JS
真实短链服务往往混合使用多种跳转手段,比如先 302 到一个中间页,再由该页通过 meta refresh 跳向最终地址。只依赖单一机制(如只看 Location 头)大概率漏掉终点。最稳的做法是「头部分析 + HTML 解析」双路并行,并始终限制跳转深度和 URL 归一化去重。


















