视频剪辑、素材收集等场景常需要获取抖音视频的直链地址。本文梳理从分享短链到视频/封面/音乐 URL 的解析思路(仅供学习研究,请遵守平台服务条款与版权法规)。
整体流程
分享短链 (v.douyin.com/xxx)
↓ 关闭自动重定向,捕获 302
重定向地址 (iesdouyin.com/share/video/{aweme_id}/...)
↓ 提取 aweme_id
官方接口 (/web/api/v2/aweme/iteminfo/)
↓ 解析 JSON
视频地址 / 封面 / 背景音乐
第一步:获取分享短链
用户在抖音 App 中点击「复制链接」,得到类似:
https://v.douyin.com/eReT43D/
这是短链,需要展开才能拿到真实的 aweme_id(视频编号)。
第二步:关闭重定向,捕获真实 URL
直接 GET 短链时,服务端会返回 302 重定向 到 www.iesdouyin.com/share/video/...,中间可能夹杂验证码页面。
调试技巧:
- 在 Postman / curl 中关闭自动跟随重定向
- 查看响应头
Location字段 - 得到重定向前的完整 URL
curl -I "https://v.douyin.com/eReT43D/" \
-H "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)"
响应示例:
HTTP/1.1 302 Found
Location: https://www.iesdouyin.com/share/video/6929752969407712527/?region=CN&...
第三步:从 URL 提取 aweme_id
从重定向 URL 的路径中截取视频 ID:
const { URL } = require('url');
const redirectUrl =
'https://www.iesdouyin.com/share/video/6929752969407712527/?region=CN&mid=...';
const pathname = new URL(redirectUrl).pathname;
// /share/video/6929752969407712527/
const awemeId = pathname.split('/')[3];
// => "6929752969407712527"
Rust 等价写法:
fn extract_aweme_id(url: &str) -> Option<String> {
let path = url::Url::parse(url).ok()?.path();
path.split('/').nth(3).map(|s| s.to_string())
}
第四步:调用官方 iteminfo 接口
GET https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids={aweme_id}
请求时需携带常见浏览器 UA,部分时期还需要 Cookie 或签名参数(接口会不定期升级)。
curl "https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=6929752969407712527" \
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \
-H "Referer: https://www.douyin.com/"
第五步:解析返回 JSON
成功时 status_code 为 0,核心数据在 item_list[0]:
{
"status_code": 0,
"item_list": [{
"aweme_id": "6929752969407712527",
"desc": "视频标题",
"video": {
"play_addr": {
"url_list": [
"https://aweme.snssdk.com/aweme/v1/playwm/?video_id=xxx&ratio=720p&line=0"
]
},
"cover": { "url_list": ["https://p3-sign.douyinpic.com/..."] },
"origin_cover": { "url_list": ["https://p3-sign.douyinpic.com/..."] },
"has_watermark": true
},
"music": {
"play_url": {
"url_list": ["https://sf6-cdn-tos.douyinstatic.com/obj/ies-music/xxx.mp3"]
}
}
}]
}
关键字段
| 字段路径 | 含义 |
|---|---|
item_list[0].desc | 视频标题/描述 |
video.play_addr.url_list[0] | 带水印播放地址 |
video.origin_cover.url_list[0] | 封面图 |
music.play_url.url_list[0] | 背景音乐 |
video.has_watermark | 是否含水印 |
提取示例:
const item = data.item_list[0];
const videoUrl = item.video.play_addr.url_list[0];
const coverUrl = item.video.origin_cover.url_list[0];
const musicUrl = item.music.play_url.url_list[0];
关于无水印
play_addr 返回的 URL 通常带 playwm(watermark),要获取无水印版本可将 URL 中的 playwm 替换为 play,但:
- 该技巧随时可能失效
- 部分视频有加密或时效签名(
x-signature参数) - 生产环境应评估合规风险
第六步:视频下载
浏览器直接打开
将 videoUrl 粘贴到浏览器地址栏即可播放或另存为。
前端 Blob 下载
async function downloadVideo(url, filename = 'video.mp4') {
const res = await fetch(url);
const blob = await res.blob();
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
link.click();
URL.revokeObjectURL(link.href);
}
服务端代理下载
跨域或防盗链场景下,可由后端转发请求:
客户端 → 你的服务器 → 抖音 CDN → 返回视频流
注意控制带宽与请求频率,避免被封 IP。
常见问题
| 现象 | 可能原因 |
|---|---|
| 短链返回验证码页 | IP 被风控,换 UA/Cookie 或降低频率 |
item_list 为空 | aweme_id 错误或视频已删除/私密 |
| 播放地址 403 | 签名过期,需重新请求接口 |
playwm 替换无效 | 接口升级,需跟进新版解析方案 |
与本站 live_crawler 的关系
live_crawler 项目专注于 直播源聚合与 CMS 解析(/getliveurl、/tvbox 等),抖音短视频解析属于独立的爬虫领域。若需集成,建议:
- 单独模块封装,与直播源逻辑解耦
- 加快照缓存,避免重复请求
- 接口变更时只改解析层,不影响主业务
小结
抖音视频解析的本质是:短链 → 重定向 → aweme_id → iteminfo API → 字段提取。掌握这条链路后,无论用 Node.js、Python 还是 Rust 实现,思路都是一致的。实际开发中需持续关注接口变动与合规要求。
评论