Python爬虫怎么抓取短视频数据_从页面分析获取真实视频URL
短视频平台HTML中无真实视频URL,因地址藏于XHR接口响应的加密字段中,需通过浏览器抓包定位接口、复现带签名的请求或用Playwright等工具执行JS获取。
为什么直接请求页面 HTML 拿不到视频 URL
短视频平台(如抖音、快手)的首页或详情页 HTML 里基本不写真实视频地址,video 标签要么没有,要么 src 是占位符或低质预览图。真实地址藏在 XHR 请求响应里,通常是 JSON 接口返回的加密字段或带签名的链接。
常见错误现象:
• 用 requests.get(url) 拿到的 HTML 里搜 "mp4" 或 "video" 一无所获
• 浏览器开发者工具里能看到网络面板有 /aweme/v1/web/video/feed/ 这类请求,但 Python 里复现失败
- 关键原因是:这些接口强制校验
Referer、User-Agent,还依赖动态生成的signature或msToken参数 - 部分接口要求登录态(
sessionid或cookie中的odin_tt),未携带会返回{"status_code":10110,"status_msg":"Forbidden"} - JS 渲染页(如抖音 PC 端)必须用无头浏览器抓首屏,否则连接口请求都触发不了
怎么定位真实视频接口(以抖音为例)
打开 Chrome 开发者工具 → Network → 切到 XHR → 刷新页面 → 找含 video、aweme、item 的请求。重点看响应体是否含 "play_addr" 或 "video_list" 字段。
典型路径:/aweme/v1/web/aweme/detail/(单视频)、/aweme/v1/web/video/feed/(信息流)。注意查询参数里的 aweme_id、count、cursor 都是关键标识。
- 别只盯着
Response标签——点Headers看Request URL全路径和Query String Parameters - 复制该请求 → 右键 →
Copy as cURL (bash)→ 粘贴到在线工具(如 curlconverter.com)转成 Pythonrequests代码,能省掉 80% 的 header 配置 - 如果接口返回空或
"status_code": 0但没数据,大概率是sign过期了——这个值通常由前端 JS 计算,不能硬编码
绕过 signature 校验的实用方案
抖音系接口的 _signature 参数是基于 URL 和时间戳用 JS 算出来的,Python 直接仿写容易出错且维护成本高。更稳的做法是复用浏览器环境。
观猹
观猹(Watcha.cn)丨AI 产品的大众点评
下载
- 用
selenium或playwright启动 Chromium,执行 JS 提取window.byted_acrawler.sign({url: 'xxx'})返回值 - 轻量替代:用
execjs运行提取出的签名函数(需先从网页源码里扒下byted_acrawler.js或对应逻辑),但 JS 更新后立刻失效 - 最省事但有代价:放弃纯
requests,改用playwright.sync_api.sync_playwright().start()直接走真实浏览器上下文,所有 header、cookie、sign 自动带上
示例(Playwright 提取视频地址):
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://www.douyin.com/video/729xxxx")
# 等待接口完成,再取 response
video_url = page.evaluate('''() => {
const req = [...performance.getEntriesByType("resource")].find(r => r.name.includes("aweme/detail"));
return req ? JSON.parse(req.responseEnd).aweme_detail.video.play_addr.url_list[0] : null;
}''')
print(video_url)
browser.close()
下载前必须检查的三个字段
拿到 url_list 里的链接别急着 requests.get(),先确认三件事:
-
url_list通常有多个地址,优先选ratio含"720p"或"1080p"的项,避开"playwm"(带水印)和"playadr"(防盗链跳转) - 检查链接是否含
?expires=和&signature=—— 这类 URL 有效期常短于 60 秒,必须立刻下载,缓存或延迟会导致403 Forbidden - 发起下载请求时,
headers必须包含原始请求中的Referer(如https://www.douyin.com/),否则返回空响应或重定向到错误页
一个容易被忽略的细节:某些平台(如小红书)的视频 URL 响应头里带 Content-Disposition: attachment; filename="xxx.mp4",但实际返回的是 HTML 错误页——这时候要先检查 response.status_code 和 response.headers.get("Content-Type") 是否为 "video/mp4"。