问答
TikTokApi 一直报 EmptyResponseException,有没有更稳的 TikTok 数据获取方式?
简短回答
EmptyResponseException 说明 TikTok 把你的自动化浏览器当成了机器人,直接返回空内容。如果只需要公开数据,用托管接口可以省掉浏览器、ms_token 和代理:okdata 查一条视频 $0.002,查一个账号 $0.002,搜索一页约 30 条视频 $0.002,失败的调用不收费。
上周五脚本在自己电脑上跑得好好的,周一部署到服务器,每次调用 video.info()、user.info() 都报 EmptyResponseException: TikTok returned an empty response。代码本身没问题。TikTokApi 是通过 Playwright 开一个无头浏览器去访问 TikTok,TikTok 的风控认定这个浏览器背后不是真人,于是回了一个空响应。
换方案之前可以先试试
库自带的报错信息里就列了几条,小规模用确实有效:
- 从已登录浏览器的 Cookie 里复制一个新的
ms_token传进去。 - 用
headless=False运行,或者换成browser="webkit"。 - 把机房 IP 换成住宅代理,请求放慢。
麻烦在于维护。token 会过期,代理要花钱,TikTok 前端一改版又可能全部失效。如果你的目的只是读取公开数据,用不着操作账号,那浏览器这一层可以整个拿掉。
不开浏览器的同等调用
| TikTokApi 里的写法 | 对应接口 | 价格 |
|---|---|---|
api.video(url=...).info() |
TikTok 视频详情 | $0.002 |
api.user(username).info() |
TikTok 账号信息 | $0.002 |
| 按关键词搜视频(社区里呼声很高的需求) | TikTok 视频搜索 | 每页 $0.002 |
video.comments() |
TikTok 视频评论 | 每页 $0.002 |
也有对应不上的:某个账号的全部作品列表、话题页、推荐流和视频下载,这里都没有。
import os, requests
API = "https://api.okdata.online/v1"
H = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
def call(path, **params):
body = requests.get(f"{API}/{path}", headers=H, params=params, timeout=60).json()
if body["code"] != "ok":
# 每个错误都会说明是否扣费、要不要重试
raise RuntimeError(f"{body['code']} charged={body['charged']} retry={body['retry']}")
return body["data"]
video = call("tiktok/videos/get", url="https://www.tiktok.com/@scout2015/video/6718335390845095173")["item"]
author = call("tiktok/users/get", username=video["author"]["username"])["item"]
print(video["metrics"]["views"], video["metrics"]["likes"], author["followers"])
代码里要改的地方
- 返回的是普通 JSON,所有平台同一种结构:单个对象在
data.item,列表在data.items,翻页看page.next_cursor。不用写异步,也不用管浏览器的启动和关闭。 - 出错时返回错误码。
upstream_busy、upstream_failed值得重试,not_found说明视频或账号已经没了。这些都不扣费,完整列表见错误说明。 - 字段名和 TikTok 原始 JSON 不一样:
playCount对应metrics.views,diggCount对应metrics.likes。
什么时候继续用 TikTokApi
你需要这里没有的东西,比如某个账号的完整作品列表;或者一个月只跑几百次请求,而且在家里的网络下还能正常用,那就留着它,开源免费。有学术身份、要做大规模研究的,官方的 Research API 才是正路。
更新于