如何使用Python从短链接/重定向链接获取爬虫所需最终真实URL
跳转链路说明
当前遇到的跳转链路共3层:
- 初始短链接:
https://naver.me/xDMa0YE6,为应用生成的短缩URL - 重定向中转URL:
https://link.naver.com/bridge?xxx,为访问短链后302跳转的中转页地址,页面内置唤起APP逻辑和目标页参数 - 最终目标URL:
https://n.news.naver.com/article/009/0004980823,为需要爬取的新闻页真实地址
直接使用bs4默认请求逻辑无法获取目标页内容的核心原因:bs4本身不自动处理跳转逻辑,且无合法请求头的请求会被Naver反爬拦截,停留在中转页。
方案1:轻量无浏览器方案(推荐,速度快)
利用requests库跟踪3xx跳转,直接从中转页URL参数中提取目标地址,无需渲染JS,效率最高。
import requests from urllib.parse import urlparse, parse_qs # 模拟普通浏览器请求头,绕过基础反爬 HEADERS = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36", "Accept-Language": "ko-KR,ko;q=0.9,en;q=0.8" } def resolve_naver_short_url(short_url: str) -> str: # 请求短链,暂时关闭自动跳转,直接获取302返回的中转页地址 resp = requests.get( short_url, headers=HEADERS, allow_redirects=False, timeout=10 ) # 从响应头拿中转页地址 if resp.status_code in (301, 302, 303, 307, 308): bridge_url = resp.headers.get("Location") else: bridge_url = resp.url # 解析中转页的查询参数,直接提取内置的最终目标URL parsed_url = urlparse(bridge_url) query_params = parse_qs(parsed_url.query) final_url = query_params["url"][0] return final_url if __name__ == "__main__": short_link = "https://naver.me/xDMa0YE6" target_url = resolve_naver_short_url(short_link) print(f"解析得到的最终URL:{target_url}") # 拿到URL后直接请求即可获取目标页HTML target_resp = requests.get(target_url, headers=HEADERS, timeout=10) target_resp.encoding = "utf-8" # 后续可直接传入bs4做解析 # from bs4 import BeautifulSoup # soup = BeautifulSoup(target_resp.text, "html.parser")
- 适配说明:如果遇到部分短链未在中转页参数中直接暴露目标地址,可将
allow_redirects参数改为True,让requests自动跟随所有3xx跳转,最终通过resp.url即可拿到跳转后的最终地址。 - 如果中转页使用JS做跳转无3xx状态码,可直接用bs4解析中转页HTML,提取meta刷新标签或JS代码中
window.location.href对应的URL即可。
方案2:浏览器模拟方案(适配高反爬场景)
如果遇到反爬规则严格、参数加密、多层JS跳转的场景,可使用playwright模拟真实浏览器行为,自动完成所有跳转逻辑,无需手动解析规则。
使用前需要先安装依赖:pip install playwright && playwright install chromium
from playwright.sync_api import sync_playwright def resolve_url_with_browser(short_url: str) -> str: with sync_playwright() as p: # 启动无头浏览器 browser = p.chromium.launch(headless=True) page = browser.new_page( user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36", locale="ko-KR" ) # 访问短链,等待网络空闲即说明已跳转到最终目标页 page.goto(short_url, wait_until="networkidle", timeout=15000) final_url = page.url browser.close() return final_url
排查要点
- 返回403错误时,更换为最新版本的浏览器User-Agent,可补充Referer请求头
- 解析参数出现乱码时,检查URL编码层数,必要时做多次URL解码
- 被强制唤起APP时,增加韩国地区的语言、地区请求头,可模拟移动端访问规避APP唤起逻辑
内容的提问来源于stack exchange,提问作者lupalupa
相关产品推荐
相关产品推荐

