做内容相关系统的人都遇到过这种事:想拿到一条抖音或小红书链接的标题、封面、作者和互动数据,每个平台一套解析规则、一套字段口径,光维护适配就要耗掉不少精力。这个接口把这个活收敛成一次 HTTP 调用——传入分享链接或口令,同步返回标题、封面、无水印直链、图集与作者信息,成功扣 1 点,失败不扣。
真正需要花心思的是三件事:错误码的一码多义、直链的时效性、以及合规义务的落地。
全文按真实接入顺序写:适用场景 → 拿 Key → 第一次调用 → 写成工具 → 排查失败 → 上生产。每节独立成块,可以从目录直接跳到需要的部分。
一、这个接口是什么,一句话版
把"每个平台一套解析规则"收敛成一次 HTTP 请求:
- 输入:分享链接、短链,或者整段分享口令(接口自动提取其中的 http(s) 地址);
- 输出:标题、描述、封面、无水印视频直链、图集、作者、互动数据;
- 模式:同步,一般 2~5 秒返回,无任务号、无轮询;
- 计费:成功解析扣 1 点,参数错误、解析失败、服务端 500 均不扣。
先把合规原文放在最前面,因为它决定这个接口能用来做什么:
本接口仅提供链接元数据解析,不存储、不复制、不分发原始内容。解析结果版权归原作者及原平台所有,仅供个人备份、内容审核、数据分析、学术研究等合理使用;禁止公开传播他人作品、二次商业转售或集成到下载分发站点。
一句话:这是分析工具,不是下载站的后端。
二、能用它做什么:六个典型场景
按落地频率排序,每个场景都标了主要依赖的返回字段——选型时对着自己的需求看第三列就行。
| 场景 | 怎么用 | 主要依赖字段 |
|---|---|---|
| 竞品内容监测 | 定时解析指定账号的分享链接,落库做点赞/评论趋势对比 | stats.like_count、comment_count、publish_time |
| 爆款内容拆解 | 采集高赞视频的标题和描述,分析钩子写法与选题规律 | title、desc、stats |
| 内容审核风控 | 对投稿/转载内容先解析元数据(作者、来源、互动量),再决定是否进人工审 | platform、author、stats |
| 自有内容备份 | 把自己发布的内容定期归档,含封面与直链 | video_url、imagelist、cover_url |
| 图集素材整理 | 批量提取图文笔记的静图与实况动图,进素材库 | imagelist、video_list(动图档) |
| 数据集构建 | 社交媒体传播数据抽样采集,做学术或算法研究 | stats 全量 + source.original_url |
两条使用建议:
- 互动数据做差值,不做绝对值。 各平台计数口径不同,部分平台不提供播放数(返回 0);同一条链接在不同时间点各解析一次,取差值才反映真实增长。1 点一次的成本,做趋势追踪完全扛得住。
- 电商和资讯类链接,字段比文件值钱。
title往往是商品名或文章标题、author是店铺或账号,做比价、内容聚合分析时不下载视频,纯解析入库,成本最低。
同时对照第一节的合规条款,把"不能做"的也说清楚:不要做去水印下载站,不要把解析结果公开传播,不要二次商业转售。返回的 source 字段里带了版权说明和使用限制,文档要求在最终用户可见界面展示——这条在第七节会落到代码上。
三、准备工作:两分钟拿到 Key
- 注册并登录开放平台控制台;
- 进入「密钥管理」,创建一个 API Key;
- 不要把 Key 写进代码或提交到 Git,先放进环境变量:
export XIAOAPIS_API_KEY="你的key"
后面所有示例都从环境变量读 Key。泄露的 Key 就是别人的免费算力,控制台支持随时重置,但账单不会退。
四、第一次调用:两条 curl 跑通
4.1 GET 版(最快验证)
curl "https://xiaoapis.com/api/video/videoparse?key=$XIAOAPIS_API_KEY&url=https://v.douyin.com/xxxxx/"
4.2 POST + JSON 版(推荐日常用)
curl -X POST "https://xiaoapis.com/api/video/videoparse?key=$XIAOAPIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "7.20 复制打开抖音 https://v.douyin.com/xxxxx/ 看看这条视频"}'
两种方法接口都支持。日常用 POST 的理由:口令里常有中文、表情和特殊字符,放 JSON 请求体比拼 query string 少一层编码问题。注意 Content-Type 用 application/json 或表单编码均可,文档两种都列了。
4.3 返回长什么样
{
"code": 200,
"msg": "success",
"data": {
"platform": "douyin",
"type": "视频",
"title": "示例标题",
"video_url": "https:// example.com/video.mp4",
"cover_url": "https:// example.com/cover.jpg",
"imagelist": [],
"author": "示例作者",
"video_format": "mp4",
"stats": {
"like_count": 40,
"comment_count": 23,
"share_count": 4,
"play_count": 0,
"collect_count": 9,
"publish_time": "2026-08-30 08:59:24"
},
"video_list": [
{
"quality": "高清", "url": "https:// example.com/hd.mp4", "resolution": "1080x1920"}
],
"source": {
"platform_label": "抖音",
"original_url": "https://www.douyin.com/video/xxxxx",
"copyright_notice": "本内容版权归原作者及原平台所有……",
"usage_restriction": "仅供个人备份、内容审核、数据分析……"
}
},
"exec_time": 2.18,
"ip": "1.2.3.4"
}
第一眼只看四个顶层字段:
| 字段 | 用途 |
|---|---|
code |
200 才是成功,其余全看 msg |
data |
全部业务数据都在这里 |
exec_time |
本次解析耗时(秒),做监控基线用 |
ip |
服务端记录的出口 IP,排查网络问题有用 |
data 里面先记住三个判断依据:video_url 非空是视频,imagelist 非空是图集,两者都空但 audio_url 非空是纯音频。别用 type 字符串做判断——它是中文枚举(视频 / 图集 / 实况图集),能跑但不健壮,换 flat 模式就失效。
五、写成可复用的工具:单文件版
下面这个脚本可以直接当命令行工具用,也是往项目里集成的基础:
#!/usr/bin/env python3
"""videoparse.py — 分享链接解析小工具。
用法:
export XIAOAPIS_API_KEY="你的key"
python3 videoparse.py "7.20 复制打开抖音 https://v.douyin.com/xxxxx/"
python3 videoparse.py https://www.xiaohongshu.com/explore/xxxxx
"""
import json
import os
import sys
import requests
ENDPOINT = "https://xiaoapis.com/api/video/videoparse"
class ParseError(RuntimeError):
"""业务失败:参数错误 / 链接失效 / 点数不足,重试无意义。"""
class NetworkError(RuntimeError):
"""网络类失败:值得退避重试。"""
def parse(url_or_text: str, *, timeout: float = 30.0) -> dict:
"""解析一条链接,返回 data 字典。口令整段传入即可。"""
key = os.environ.get("XIAOAPIS_API_KEY")
if not key:
raise ParseError("未设置 XIAOAPIS_API_KEY 环境变量")
try:
resp = requests.post(
ENDPOINT,
json={
"key": key, "url": url_or_text, "flat": 2},
timeout=timeout,
)
except requests.RequestException as exc:
raise NetworkError(f"请求失败: {exc}") from exc
try:
body = resp.json()
except ValueError:
raise NetworkError(f"HTTP {resp.status_code},返回非 JSON: {resp.text[:200]}")
if body.get("code") != 200:
# 400 一码多义:参数错误 / 链接失效 / 点数不足,看 msg 区分
raise ParseError(f"[{body.get('code')}] {body.get('msg')}")
return body["data"]
def describe(data: dict) -> str:
"""把 data 压成一段可读文本。按能力判断形态,不依赖 type 字符串。"""
lines = [f"平台: {data.get('platform')} 标题: {data.get('title') or '(无)'}"]
stats = data.get("stats") or {
}
lines.append(
f"互动: 赞 {stats.get('like_count', 0)} 评 {stats.get('comment_count', 0)}"
f" 藏 {stats.get('collect_count', 0)} 播 {stats.get('play_count', 0)}"
)
if data.get("video_format") == "hls":
lines.append(f"视频: 流媒体(m3u8) {data['video_url']}")
elif data.get("video_url"):
lines.append(f"视频: {data['video_url']}")
images = data.get("images") or []
if images:
lines.append(f"图集: {len(images)} 张,首图 {images[0]}")
if data.get("audio_url"):
lines.append(f"音频: {data['audio_url']}")
notice = (data.get("source") or {
}).get("copyright_notice", "")
if notice:
lines.append(f"版权: {notice}")
return "\n".join(lines)
if __name__ == "__main__":
if len(sys.argv) < 2:
print(__doc__)
sys.exit(1)
try:
print(describe(parse(sys.argv[1])))
except ParseError as exc:
print(f"解析失败: {exc}", file=sys.stderr)
sys.exit(2)
except NetworkError as exc:
print(f"网络异常: {exc}", file=sys.stderr)
sys.exit(3)
退出码有意分成了三种:0 成功、2 业务失败、3 网络异常。放进 cron 或管道时,上游脚本靠退出码就能决定"放弃还是重试",不用解析 stderr。
六、失败排查表:400 是个筐,别什么都往里装
| 现象 | code | 原因 | 处理 |
|---|---|---|---|
| 正常返回 | 200 | 成功 | — |
| 密钥无效/被禁 | 403 | Key 错误、被重置、无权限 | 检查环境变量,去控制台确认 Key 状态;不要重试 |
| 各种失败 | 400 | 参数错误 / 链接失效 / 链接无法访问 / 点数不足 | 先看 msg;参数与链接问题重试无意义,点数不足去充值 |
| 服务端错误 | 500 | 平台内部错误 | 不扣费,可退避重试 1~2 次 |
400 的四种含义里最隐蔽的是点数不足:账户余额不够 1 点时,返回的也是 400,msg 会提示点数问题。批量任务半夜挂掉,八成是这两种:链接批量失效,或者点数烧完了。监控上建议对 msg 做关键字分类再告警,不然告警群会变成猜谜群。
七、拿到直链之后:三件事决定它能不能进生产
7.1 直链有时效,解析即转存
video_url 指向平台 CDN,过一段时间就失效。业务库里存原始直链,过两周全成死链。正确顺序:
解析成功 → 立即下载 → 转存自己的对象存储 → 库里只存自己的 key
如果 video_format 是 hls,直链是 m3u8 播放列表,requests.get 下来不是视频文件,用 ffmpeg -i <m3u8> -c copy out.mp4 转封装,或在业务上标记为流媒体交给播放器。
7.2 没有限频说明,就按保守值限速
文档没有写明确的 QPS 上限,这意味着两件事:不要拿接口做压测去试边界,也不要裸奔并发。经验值:批量任务把并发压在个位数、加令牌桶限速,瞬时抖动留余量。等平台给出明确限频文档,再按文档放宽。
7.3 合规字段要展示,不是存档
返回的 source.copyright_notice 和 usage_restriction,文档要求在最终用户可见界面展示。做产品时给这两个字段留渲染位置——它要从解析层一路透传到界面,中间任何一层丢掉,上线检查时都会被打回。
八、上生产前的六项检查
- Key 走环境变量或密钥管理服务,代码和日志里不出现明文;
- 失败分类:
ParseError不重试、NetworkError退避重试、500 重试 1~2 次,退出码区分(第五节脚本已实现); - 解析即转存,库里不存平台直链;
- 监控
exec_time和成功率:同步接口的好处是耗时可观测,2 秒涨到 15 秒就是平台在抖,提前于用户感知; - 点数告警:按日均用量设余额阈值,别让批量任务半夜死在 400 上;
- 来源与版权信息展示到位,合规条款逐条对照文档原文。
九、常见问题
Q1:整段口令直接传行吗?
行。接口自动提取口令里的 http(s) 地址,不用自己写正则。这也是它比多数同类接口省一步的地方。
Q2:同步接口会不会超时?
一般 2~5 秒返回。客户端超时建议给到 30 秒(海外平台链路长),超时后不要立即重试——可能服务端已在处理,重试会重复扣点。
Q3:图集怎么拿全?
静图遍历 images(元素是字符串 URL);实况图集的动图藏在 video_list,quality 形如 动图1、动图2。只扫 images 会丢动图。
Q4:play_count 是 0 正常吗?
正常。部分平台不提供播放数,返回 0 不是异常。互动数据做同链接多次解析的差值才有意义,横向比绝对值会失真。
Q5:失败扣点吗?
不扣。只有 code=200 扣 1 点,400、500 都不扣。成本线性:一千次成功解析约 10 元。
Q6:支持哪些平台?
覆盖短视频、直播、音乐、电商、资讯与海外平台,共 130+ 个且持续增加中:国内如抖音、快手、小红书、B站、微博、视频号、QQ音乐、淘宝、美团等;海外如 TikTok、YouTube、Instagram、X(Twitter)等。代码里不用穷举平台名——返回的 platform 是归一化标识,按"有没有 video_url / images / audio_url"判断内容形态即可,平台增减不影响分支逻辑。