怎么按关键词批量采集 TikTok Shop 商品评价
按顺序用三个接口:TikTok Shop 商品搜索、商品详情,再逐页拉商品评价。下面的示例一共 10 次调用,花费 $0.022;失败的调用不扣费。
更新于
要做的事:你准备在 TikTok Shop 上卖、采购或者对比某类商品,想知道买家对已经在卖的那些商品怎么说。平均星级把最有用的东西藏起来了,评价正文才会告诉你哪个尺码偏小、哪根带子一周就断、买家有什么意外的惊喜。这里的做法是:按关键词搜商城,挑评价最多的几个商品查详情,再一页页读它们的评价。最后得到两个 CSV:商品表(价格、销量、评分、店铺)和评价表(星级、内容、购买的款式、晒图、是否已验证购买)。
TikTok 自己的 Shop API 是给卖家读自己店铺用的,帮不上看别人商品的忙,区别见没有卖家账号能不能用 API 拿 TikTok Shop 商品和评价。下面这几个接口读的是买家能看到的公开商品页,用 API key 调用,不需要 TikTok 账号。
分步操作
三个接口都有 country 参数,填商城所在市场的 ISO 国家代码。默认是 US,也是数据最全的市场。其他市场填对应代码也能用,只是覆盖薄一些,先试一次再批量跑。三次调用用同一个 country;跨市场比价前先看 currency。
第一步:搜商品
TikTok Shop 商品搜索的参数是 query 和 country。一次调用返回约 20 个商品,每次 $0.004。每个商品有 id、url、title、price、original_price、currency、sold、rating、reviews(评价数)、一张图片和 shop(店铺 ID 和名称)。挑哪些商品值得读评价,看 reviews。
curl -G "https://api.okdata.online/v1/tiktok/shop/products/search" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'query=posture corrector' \
--data-urlencode 'country=US'
第二步:查每个商品的详情
TikTok Shop 商品详情用商品 id,或者用 url 传商品页链接(比如 https://www.tiktok.com/shop/pdp/1731859027465331722),再加上 country。每次 $0.002,返回当前价格和折扣、销量、评分、评价数和全部图片。加上 view=full,ext 里还有 shop_rating、shop_followers 和商品的 specifications,材质、尺寸这类信息就列在那里。
curl -G "https://api.okdata.online/v1/tiktok/shop/products/get" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'id=1731859027465331722' \
--data-urlencode 'country=US' \
--data-urlencode 'view=full'
第三步:逐页读评价
TikTok Shop 商品评价的商品 id 必填,另加 country。一次调用返回约 20 条评价,每次 $0.002。每条有 rating(1 到 5 星)、text、variant(买的尺码或颜色)、images(买家晒图)、verified_purchase、published_at 和 author_name(商城一般会打码)。下一页就把 page.next_cursor 作为 cursor 传回去;page.has_more 为 false 时停下。
curl -G "https://api.okdata.online/v1/tiktok/shop/products/reviews/list" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'id=1731859027465331722' \
--data-urlencode 'country=US'
第四步:用 Python 串起来
脚本对一个关键词跑完三步,写出 shop_products.csv 和 shop_reviews.csv。REVIEW_PAGES 控制每个商品读几页评价,也就控制了花费上限。
import csv
import os
import requests
API = "https://api.okdata.online"
HEADERS = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
QUERY, COUNTRY = "posture corrector", "US"
PRODUCTS = 3 # 读几个商品
REVIEW_PAGES = 2 # 每个商品读几页评价;每页一次调用
def get(path, **params):
body = requests.get(API + path, headers=HEADERS, params={**params, "country": COUNTRY}, timeout=60).json()
if body["code"] == "not_found":
return None # 已下架:不扣费
if body["code"] != "ok":
raise RuntimeError(f"{body['code']}: {body['message']} (charged: {body['charged']})")
return body
found = get("/v1/tiktok/shop/products/search", query=QUERY)["data"]["items"]
found = sorted(found, key=lambda p: p["reviews"] or 0, reverse=True)[:PRODUCTS]
products, reviews = [], []
for p in found:
body = get("/v1/tiktok/shop/products/get", id=p["id"], view="full")
if not body:
continue
products.append(body["data"]["item"])
cursor = None
for _ in range(REVIEW_PAGES):
page = get("/v1/tiktok/shop/products/reviews/list", id=p["id"], **({"cursor": cursor} if cursor else {}))
if not page:
break
reviews.extend(page["data"]["items"])
if not page["page"]["has_more"]:
break
cursor = page["page"]["next_cursor"]
with open("shop_products.csv", "w", newline="", encoding="utf-8-sig") as f:
out = csv.writer(f)
out.writerow(["product_id", "title", "price", "original_price", "currency", "sold", "rating", "reviews", "shop", "shop_rating"])
for p in products:
out.writerow([p["id"], p["title"], p["price"], p["original_price"], p["currency"], p["sold"],
p["rating"], p["reviews"], p["shop"]["name"], p["ext"].get("shop_rating")])
with open("shop_reviews.csv", "w", newline="", encoding="utf-8-sig") as f:
out = csv.writer(f)
out.writerow(["product_id", "review_id", "rating", "text", "variant", "photos", "verified", "published_at"])
for r in reviews:
out.writerow([r["product_id"], r["id"], r["rating"], r["text"], r["variant"],
len(r["images"] or []), r["verified_purchase"], r["published_at"]])
按默认值跑就是上面的示例:10 次调用,约 120 条评价。10 个商品、每个读 5 页评价的话,一共是 $0.124。
注意事项
- 只打星不写字。 有些买家只给星级,这时
text是空字符串。总结文字前先把这些过滤掉,但统计星级分布时要留着。 - 评价没有点赞数。 TikTok Shop 的评价不显示点赞,所以
likes一直是 null,meta.unavailable里写的是platform。 - 顺序。 评价按商城自己的顺序返回,没有排序参数。读几页只是一个样本;商品的
rating和reviews才覆盖全部评价。 - 销量。
sold是商品页上显示的数字。每天对比一次可以看出大致的销售趋势,但它不是订单数。 - 日期。 商城只显示日期的,
published_at就是那一天。 - 只有公开数据。 GMV、流量来源、广告花费这些都在卖家后台里,这里一样也拿不到。想估算销售额,只能用每天的
sold差值乘以价格粗算。 - 已下架的商品。 商品没了会返回
not_found,不扣费,其他错误也一样。重试时带上Idempotency-Key请求头更稳妥:24 小时内同样的请求配同样的 key,会拿回存下的结果,meta.replayed为true,不再扣费。
示例花费
在美国站搜一次 posture corrector(驼背矫正带),取评价最多的 3 个商品查详情,每个再读 2 页评价(约 40 条)
| 接口 | 调用次数 | 单价 | 小计 |
|---|---|---|---|
| TikTok Shop 商品搜索 | 1 | $0.004 | $0.004 |
| TikTok Shop 商品详情 | 3 | $0.002 | $0.006 |
| TikTok Shop 商品评价 | 6 | $0.002 | $0.012 |
| 合计 | 10 | $0.022 |
按本页生成时的价格计算。失败的调用不扣费。
在你的 AI 里用(MCP)
先接好 MCP 服务,然后直接说你要什么。智能体会自己找到这些接口、看清价格,再用你的余额调用。
可以这样说在美国站 TikTok Shop 搜 posture corrector,取评价最多的 3 个商品,给我每个的价格、销量、评分和店铺,再每个读 40 条左右评价,总结买家夸什么、骂什么。
智能体第一次调用 call 工具时发送的内容
{
"endpoint": "tiktok.shop.products.search",
"params": {
"query": "portable coffee maker"
},
"idempotency_key": "<新的 UUID>"
}