抖音榜单监测 API 教程
用一个 SandBase 密钥监测抖音高赞榜并把每条视频解析成稳定的 aweme_id——轮询榜单、按 ID 去重,无需登录、无需 SDK。

抖音的榜单能露出此刻正在飙升的内容——但监测任务需要的不止是一张快照。你想按计划轮询榜单,识别出哪些视频已经见过,并把一切挂到一个稳定标识上,让你的去重和存储在多次运行之间保持干净。这篇教程接的正是这条链路:轮询高赞榜、把每条视频解析成规范的 aweme_id,再把一条去重后的流交给你的 Agent。
一个 SandBase API 密钥,不需要登录抖音,不需要 SDK。每个端点的 API 参考是其参数和响应信封(id/status/model/outputs[0].data)的权威来源;下面展示的业务载荷字段名只是一个示例结构、并非保证的 schema,请以一份真实响应为准核对。
要了解抖音完整的端点面,见 抖音公开数据 API 总览。准备动手?获取 SandBase API 密钥。
先说结论
- 两个端点——
douyin/billboard/hot-total-high-like-list和douyin/web/aweme-id——用同一个密钥读取。- 榜单把排名视频嵌在
data.data.objs下并带上游code;每个条目带item_id、item_title、nick_name、like_cnt。- 把视频 URL 解析成规范的
aweme_id,让去重和存储都挂在一个稳定标识上。- 仅公开、只读数据。你这边无需发帖、无需登录;用 SandBase API 密钥鉴权即可。
方案
- 轮询榜单。 调用
douyin/billboard/hot-total-high-like-list,检查上游code,从data.data.objs读排名视频。 - 解析稳定 ID。 对每条视频调用
douyin/web/aweme-id拿规范的aweme_id。 - 去重并做增量。 维护一个已见 ID 集合;只输出自上次运行以来新增的条目。
SandBase 上的抖音 API 页面——billboard 簇里包含高赞榜端点。
第 1 步 —— 轮询榜单
每个 SandBase Model API 调用都是向 /v1/api/<vendor>/<path> 发一个 POST,把密钥放在 Authorization 头里。读 outputs 前先按 status 分支判断,而且——因为榜单包了一层——读 data.objs 前先检查上游 code。
import os
import requests
SANDBASE = "https://api.sandbase.ai/v1/api"
HEADERS = {
"Authorization": f"Bearer {os.environ['SANDBASE_API_KEY']}",
"Content-Type": "application/json",
}
def call(path: str, body: dict) -> dict:
resp = requests.post(f"{SANDBASE}/{path}", headers=HEADERS, json=body, timeout=90)
resp.raise_for_status()
out = resp.json()
if out.get("status") != "completed":
raise RuntimeError(out.get("error", {}).get("message", f"{path} 未完成"))
return out["outputs"][0]["data"]
def billboard() -> list[dict]:
data = call("douyin/billboard/hot-total-high-like-list", {})
if data.get("code") != 0:
raise RuntimeError(data.get("message", "抖音上游错误"))
# 参考只保证信封,业务字段随端点而定、以真实响应为准。
return data.get("data", {}).get("objs", [])
下面是一个示例响应结构——字段名并非保证的 schema、以真实响应为准,请把字段和取值当作示例,并对照真实响应核对,因为负载会随时间变化:
{
"id": "d4727a3b-18ea-403d-b90b-db093210ecac",
"status": "completed",
"model": "douyin/billboard/hot-total-high-like-list",
"outputs": [
{
"data": {
"code": 0,
"data": {
"objs": [
{ "item_id": "…", "item_title": "…", "nick_name": "…", "like_cnt": 0, "item_url": "…" }
]
}
}
}
]
}
端点 API 参考是每个参数名和响应路径的事实来源。
第 2 步 —— 解析稳定的 aweme_id
榜单条目带一个 item_id,但做监测你想要的是分享 URL 所解析出的规范 aweme_id——它才是你用来去重和存储的标识。把视频 URL 喂给 douyin/web/aweme-id,它以纯字符串返回该 ID:
def resolve_aweme_id(video_url: str) -> str:
return call("douyin/web/aweme-id", {"url": video_url})
因为 call 已经按 status 分支过了,这个端点把 ID 字符串直接返回在 data 下。传一个抖音视频或分享 URL,你就拿回一个可以跨运行信赖的规范 ID。
aweme-id 端点把视频 URL 解析成一个规范的 aweme_id 字符串。
第 3 步 —— 跨运行去重与增量
现在是监测循环。在运行之间维护一个已见 ID 集合(这里放内存;生产里用存储托底)。每次轮询,解析 ID,丢掉见过的,只输出新增的条目:
SEEN: set[str] = set()
def poll_new() -> list[dict]:
fresh = []
# 参考只保证信封,业务字段随端点而定、以真实响应为准。
for i, obj in enumerate(billboard()):
item_url = obj.get("item_url")
if not item_url:
continue
aweme_id = resolve_aweme_id(item_url)
if aweme_id in SEEN:
continue
SEEN.add(aweme_id)
fresh.append(
{
"aweme_id": aweme_id,
"rank": i + 1,
"title": obj.get("item_title"),
"author": obj.get("nick_name"),
"likes": obj.get("like_cnt"),
}
)
return fresh
for entry in poll_new():
print(f"新增 #{entry['rank']} {entry['title']} — {entry['author']}({entry['likes']} 赞)")
按计划跑,每次执行只打印发生变化的部分。因为一切都挂在规范的 aweme_id 上,一条在多次轮询之间都留在榜上的视频会被识别为同一项——不会重复告警、不会重复存储。
为什么这里统一信封很关键
两个端点回来时用的是相同的 { id, status, model, outputs } 信封,所以脆弱的那部分——鉴权、传输、status 处理、重试——只在 call 里写一次,两个都复用。榜单把行嵌在 data.data.objs 下、藏在上游 code 后面;aweme-id 端点把一个裸字符串返回在 data 下。这就是你代码需要知道的仅有两条每端点事实,而且两条都能在一次真实响应里看到。
正是这种分离让监测器容易扩展。想给每个新条目补更多细节?在同一个辅助函数后面再加一个调用,用你已经解析出的 aweme_id 作键,去重逻辑不用变。你的注意力停在监测信号上——什么刚开始流行——而不是停在解析怪癖上。当你需要的不止是榜单和 ID 时,去抖音总览里查到合适的端点,并在接入前确认它的参数。
局限与边界
- 仅公开、只读数据。 不发帖、不关注、不涉及私有或仅账号可见的数据。
- 负载结构与上游 code。 榜单嵌在
data.data.objs下、藏在code后;aweme-id 在data下返回字符串。先看一次真实响应、读一遍结构。 - 速率与量级。 把响应当作尽力而为的读取;遇到 HTTP 429 等瞬时错误时按退避策略重试,并控制轮询节奏。
- 以线上参考核对端点。 可用性和字段可能变化;在依赖某个具体端点前先确认。
- 这不是官方合作。 SandBase 提供对公开数据的统一访问;请尊重抖音条款和适用规则。
常见问题
我需要抖音登录吗?
不需要。你用自己的 SANDBASE_API_KEY 向 SandBase 鉴权。这些读取端点不需要你这边有抖音账号或 OAuth。
榜单已经有 item_id 了,为什么还要解析 aweme_id?
规范的 aweme_id 是分享 URL 所解析出的标识——用它去重和存储,能让你的键保持一致,无论你从哪种 URL 形态起步。
我该多久轮询一次? 按你的需要控制节奏,并用退避处理瞬时错误。把榜单当作尽力而为的读取,而不是实时流。
动手搭
创建一个 SandBase API 密钥,轮询榜单,解析 ID,跨运行做增量。准备好后: