抖音 API Python 教程:搜索、视频、账号和评论(2026)
抖音开放平台服务的是授权了你应用的用户,所以这篇教程改用 okdata 的五个接口,直接用 requests 调:抖音视频搜索、视频详情、账号信息、账号作品列表和视频评论。示例一共 6 次调用,花费 $0.03;失败的调用不扣费。
更新于
抖音有没有官方 API 能干这件事?抖音开放平台是围绕用户授权设计的。它的“获取用户公开信息”接口要传 access_token 和 open_id,这两个值只有在用户登录你的应用、授权 user_info 权限之后才拿得到。开放平台也列出了关键词视频搜索(scope 为 aweme.dy.video_search),但要单独申请到这项权限才能调用。如果你做的是给授权用户用的应用,或者你的应用已经拿到了这项权限,走官方渠道是对的。两者的边界可以看抖音开放平台能拿到哪些数据。
这篇教程讲的是另一种情况:想在 Python 脚本里读抖音公开数据,不想走应用审核、OAuth 授权,也不想碰 Cookie 和签名。最后你会得到一个能复用的小客户端:一个负责报错和重试的函数、一个带页数上限的翻页器、五个接口,以及一份 JSON 报告。
分步操作
第一步:准备环境
需要 Python 3.9 以上、requests,以及放在环境变量里的 API key。没有 SDK 要装。
pip install requests
export OKDATA_API_KEY=okd_...
每次调用都是对 https://api.okdata.online 加接口路径发 GET 请求,key 放在 Bearer 头里。成功时 "code" 为 "ok",数据在 data 里,列表接口还会带 page。出错时返回 code、message、request_id 和一个 retry 提示:yes 表示稍后可以重试(有 retry_after_seconds 就按它等),其他值说明要改请求或者跳过。
第二步:搜索视频
抖音视频搜索接收 query 和 sort,sort 可选 relevance(默认)、latest 或 most_liked。一次调用返回约 20 条视频,每次 $0.02。每条有 id、文案 text、作者 author(其中 author.id 就是 sec_uid)、包含点赞、评论、分享、收藏的 metrics,以及 published_at 和 hashtags。图文作品的 type 为 "image",图片在 images 里。
curl -G "https://api.okdata.online/v1/douyin/videos/search" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'query=露营装备' \
--data-urlencode 'sort=most_liked'
第三步:按 ID 或链接取单条视频
抖音视频详情接收 id 或 url,v.douyin.com 的分享链接可以直接当 url 传,每次 $0.002。已知视频想刷新数据,或者手上只有别人发来的一个链接时用它。加 view=full 还能拿到 ext.duration_ms(时长)和 ext.music(音乐名)。
curl -G "https://api.okdata.online/v1/douyin/videos/get" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'id=7438215906473820455' \
--data-urlencode 'view=full'
第四步:作者的账号信息
抖音账号信息的 id 传 sec_uid,或者 url 传主页链接、分享链接,每次 $0.002。返回 followers、following、posts(作品数)、likes(获赞总数)、bio 和 verified。username 是 App 里显示的抖音号。
curl -G "https://api.okdata.online/v1/douyin/users/get" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'id=MS4wLjABAAAAk3Vb9QpZr2LxWc7nYfTe1HdJ6sGuA0mKiOyPzR4tE8w'
第五步:作者的作品列表
抖音账号作品列表必须传 sec_uid 作为 id,一次返回约 20 条,从新到旧,每次 $0.002。翻页和其他列表接口一样用 cursor。
第六步:视频下的评论
抖音视频评论必须传视频 id,一次返回约 20 条一级评论,每次 $0.002,按抖音自己的热度排序(sort 只有 hot 一个值)。每条评论有 text、author、likes、replies、published_at 和 ip_location。
curl -G "https://api.okdata.online/v1/douyin/videos/comments/list" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'id=7438215906473820455'
第七步:完整脚本
脚本跑的就是上面的示例:搜索,取点赞最多的视频,拉它的详情、作者信息和作者最新作品,再读两页评论,写进 douyin_report.json。call 给每次逻辑调用生成一个 Idempotency-Key,重试时沿用同一个 key,所以重试的请求不会被扣两次钱。
import json
import os
import time
import uuid
import requests
API = "https://api.okdata.online"
SESSION = requests.Session()
SESSION.headers["Authorization"] = f"Bearer {os.environ['OKDATA_API_KEY']}"
COMMENT_PAGES = 2 # 每页一次调用
class ApiError(Exception):
def __init__(self, body):
super().__init__(f"{body['code']}: {body['message']} (request {body['request_id']})")
self.code = body["code"]
def call(path, **params):
key = str(uuid.uuid4()) # 重试沿用同一个 key:重放不会再次扣费
for attempt in range(3):
body = SESSION.get(API + path, params=params, headers={"Idempotency-Key": key}, timeout=60).json()
if body["code"] == "ok":
return body
if body.get("retry") == "yes" and attempt < 2:
time.sleep(body.get("retry_after_seconds") or 5)
continue
raise ApiError(body)
def pages(path, max_pages, **params):
"""逐页返回结果;到 max_pages 或 has_more 为 false 时停。"""
cursor = None
for _ in range(max_pages):
body = call(path, **params, **({"cursor": cursor} if cursor else {}))
yield from body["data"]["items"]
if not body["page"]["has_more"]:
return
cursor = body["page"]["next_cursor"]
found = call("/v1/douyin/videos/search", query="露营装备", sort="most_liked")["data"]["items"]
if not found:
raise SystemExit("no videos for that query")
top = max(found, key=lambda v: v["metrics"]["likes"] or 0)
video = call("/v1/douyin/videos/get", id=top["id"], view="full")["data"]["item"]
author = call("/v1/douyin/users/get", id=video["author"]["id"])["data"]["item"]
latest = call("/v1/douyin/users/videos/list", id=author["id"])["data"]["items"]
comments = list(pages("/v1/douyin/videos/comments/list", COMMENT_PAGES, id=video["id"]))
report = {
"video": {"id": video["id"], "text": video["text"], "likes": video["metrics"]["likes"],
"comments": video["metrics"]["comments"], "music": video.get("ext", {}).get("music")},
"author": {"sec_uid": author["id"], "name": author["name"], "followers": author["followers"],
"videos": author["posts"], "likes": author["likes"]},
"latest_videos": [{"id": v["id"], "text": v["text"], "published_at": v["published_at"],
"likes": v["metrics"]["likes"]} for v in latest],
"comments": [{"text": c["text"], "likes": c["likes"], "replies": c["replies"],
"ip_location": c["ip_location"]} for c in comments],
}
with open("douyin_report.json", "w", encoding="utf-8") as f:
json.dump(report, f, ensure_ascii=False, indent=2)
想读得更多,把 COMMENT_PAGES 调大,或者把作品列表那一步也换成 pages。20 条视频各读 10 页评论是 200 次调用,花费 $0.40。
注意事项
- 没有播放量。 抖音不公开播放数,所以每条视频的
metrics.views都是 null,meta.unavailable里写的原因是platform。title也是 null,抖音的文案在text里。 - 账号有三种 ID。 账号类接口要的是 sec_uid(以
MS4wLjABAAAA开头);抖音号在username;数字 uid 在view=full时的ext.uid里。详见怎么获取抖音 sec_uid。 - 链接可以直接传。 视频详情和账号信息都接受分享链接,各种链接格式的区别见抖音分享链接怎么转成视频 ID。
- 删掉的不收钱。 已删除的视频或被封的账号返回
not_found,不扣费。脚本会抛出code == "not_found"的ApiError,批量跑时捕获它、跳过即可。 - 回复只有数量。 评论带
replies(下面有几条回复),但没有回复正文。 - 花费由上限控制。 每页一次调用,所以
pages的max_pages同时就是花费上限。出错的调用不花钱。
要一次导出很多条视频的评论,可以看分步教程批量导出抖音视频评论,从一次搜索直接到 CSV。想从评论里提炼观点,看怎么把抖音评论整理成情感分析摘要。
示例花费
搜一次“露营装备”,取点赞最多的视频详情、作者信息和最新作品,再读这条视频下两页评论
| 接口 | 调用次数 | 单价 | 小计 |
|---|---|---|---|
| 抖音视频搜索 | 1 | $0.02 | $0.02 |
| 抖音视频详情 | 1 | $0.002 | $0.002 |
| 抖音账号信息 | 1 | $0.002 | $0.002 |
| 抖音账号作品列表 | 1 | $0.002 | $0.002 |
| 抖音视频评论 | 2 | $0.002 | $0.004 |
| 合计 | 6 | $0.03 |
按本页生成时的价格计算。失败的调用不扣费。
在你的 AI 里用(MCP)
先接好 MCP 服务,然后直接说你要什么。智能体会自己找到这些接口、看清价格,再用你的余额调用。
可以这样说在抖音搜“露营装备”,打开点赞最多的那条视频,查一下作者的账号信息和最近发的作品,再读这条视频下前两页评论,总结评论区大家在问什么。
智能体第一次调用 call 工具时发送的内容
{
"endpoint": "douyin.videos.search",
"params": {
"query": "露营装备"
},
"idempotency_key": "<新的 UUID>"
}