怎么批量导出视频号视频的评论和回复
按顺序用四个接口:视频号视频搜索、作品详情(把搜索结果里 export/ 开头的 ID 换成数字作品 ID)、作品评论、评论回复。下面的示例一共 14 次调用,花费 $0.24;失败的调用不扣费。
更新于
要做的事:某个产品或话题在视频号上有人在聊,你想看的是观众在视频下面写了什么,而不只是博主自己说了什么。视频号的视频没有网页,评论也没有公开的入口,平时只能拿着手机在 App 里一条条翻。这里的做法是:先搜索,把要留的视频逐个查一次详情,然后一页页读评论,再把值得看的评论展开看回复。最后得到一张表,评论和回复都在里面,每条带内容、昵称、点赞数、时间,以及微信在评论旁边显示的 IP 属地。
有个地方很容易卡住:搜索结果和评论接口用的不是同一种 ID。搜索给的是 export/ 开头的加密 ID,评论接口要的是数字作品 ID。作品详情接口负责把前者换成后者,所以下面的流程里它夹在搜索和评论之间。
分步操作
第一步:搜视频
调用视频号视频搜索,query 填你会在微信“搜一搜”里输入的词。sort 可选 relevance(默认,综合)、latest(最新)或 popular(最热);只想要近期视频的话,published_within 可以填 day、week 或 half_year。一次调用最多返回约 10 条视频,每次 $0.02。
curl -G "https://api.okdata.online/v1/wechat_channels/videos/search" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'query=露营装备' \
--data-urlencode 'sort=popular' \
--data-urlencode 'published_within=half_year'
每条结果有描述 text、发布时间 published_at、author 下的账号名称和头像、metrics.likes,url 是封面图。这一步评论数是 null,author.id 也是空的,因为微信搜一搜本身不给这些。id 长这样:export/UzFfBgAAigSMv7F8h8d7wY6qhwxyunx6wtIhB9zjKomRhS82ch。它会过期,所以要在同一次运行里接着用,别存起来下周再查。
第二步:逐个查作品详情
把 export/ 开头的 ID 作为 id 传给视频号作品详情,每次 $0.02。手上是 App 里复制的分享链接也行,写成 url=https://weixin.qq.com/sph/AqR7tLm2Kd。返回里有数字作品 id(比如 14987320651142873906)、author.id 里的账号 ID,以及 metrics.likes、metrics.comments、metrics.shares 和 metrics.favorites。到这一步才知道哪些视频的评论多到值得读。数字 ID 不会过期,留着它。
curl -G "https://api.okdata.online/v1/wechat_channels/videos/get" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'id=export/UzFfBgAAigSMv7F8h8d7wY6qhwxyunx6wtIhB9zjKomRhS82ch' \
--data-urlencode 'fields=id,text,author.id,author.name,metrics'
第三步:读评论
视频号作品评论的 id 填数字作品 ID。每页约 25 条一级评论,按热度排,每次 $0.015。每条有 id、text、author.name、likes、replies、published_at 和 ip_location。要下一页,就把 page.next_cursor 原样作为 cursor 传回去;page.has_more 为 false 时停下。
curl -G "https://api.okdata.online/v1/wechat_channels/videos/comments/list" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'id=14987320651142873906'
第四步:展开回复
视频号评论回复要两个 ID:id 是一级评论的 ID,post_id 是这条评论所在视频的数字 ID。每页约 20 条回复,每次 $0.015,每条回复的 parent_id 就是它回复的那条评论。
curl -G "https://api.okdata.online/v1/wechat_channels/comments/replies/list" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'id=14987411208833651275' \
--data-urlencode 'post_id=14987320651142873906'
第五步:用 Python 串起来
下面的脚本把四步跑完,写成一个 CSV,level 列标明这一行是评论还是回复。MAX_PAGES 控制每条视频读几页评论,也就控制了花费上限。
import csv
import os
import requests
API = "https://api.okdata.online"
HEADERS = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
MAX_PAGES = 1 # 每条视频读几页评论;每页一次调用
VIDEOS = 5 # 读几条视频
THREADS = 3 # 一共展开几条评论的回复
def get(path, **params):
body = requests.get(API + path, headers=HEADERS, params=params, 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
hits = get("/v1/wechat_channels/videos/search", query="露营装备", sort="popular")["data"]["items"]
hits = sorted(hits, key=lambda h: h["metrics"]["likes"] or 0, reverse=True)[:VIDEOS]
videos = []
for h in hits:
body = get("/v1/wechat_channels/videos/get", id=h["id"]) # export/... 换成数字 ID
if body:
videos.append(body["data"]["item"])
rows, top = [], []
for v in videos:
cursor = None
for _ in range(MAX_PAGES):
body = get("/v1/wechat_channels/videos/comments/list", id=v["id"], **({"cursor": cursor} if cursor else {}))
if not body:
break
for c in body["data"]["items"]:
rows.append([v["id"], "comment", c["id"], c["text"], c["author"]["name"], c["likes"], c["ip_location"], c["published_at"]])
top.append((c["likes"] or 0, c["id"], v["id"]))
if not body["page"]["has_more"]:
break
cursor = body["page"]["next_cursor"]
for _, comment_id, video_id in sorted(top, reverse=True)[:THREADS]:
body = get("/v1/wechat_channels/comments/replies/list", id=comment_id, post_id=video_id)
for r in (body["data"]["items"] if body else []):
rows.append([video_id, "reply", r["id"], r["text"], r["author"]["name"], r["likes"], r["ip_location"], r["published_at"]])
with open("channels_comments.csv", "w", newline="", encoding="utf-8-sig") as f:
out = csv.writer(f)
out.writerow(["video_id", "level", "id", "text", "user", "likes", "ip_location", "published_at"])
out.writerows(rows)
按默认值跑,就是 1 次搜索、5 次详情、5 页评论、3 页回复,也就是上面的示例。每条视频读 3 页评论的话,要多 10 次评论调用,再加 $0.15。
注意事项
- 搜索 ID 会过期。
export/开头的 ID 只在一小段时间内有效。拿到后马上用作品详情换成数字id,存数字 ID。 - 回复数可能缺失。 微信不一定返回回复数,所以
replies可能是 null。脚本因此按点赞挑要展开的评论;没有回复的评论只会拿到一个空页。 - 没有播放量。 视频号不公开播放次数,
metrics.views是 null,meta.unavailable里标的原因是platform。 - 评论者 ID。 评论者是视频号账号时,
author.id以@finder结尾;有些以@stranger结尾,账号类接口不认这种 ID。 - 排序。 评论按热度返回,没有按最新排的选项。时间重要的话,自己按
published_at排。 - 重试和失效视频。 每次调用带一个
Idempotency-Key请求头:24 小时内同样的请求配同样的 key,会拿回上次存下的结果,meta.replayed为true,不再扣费。搜索之后被删掉的视频返回not_found,不扣费。
示例花费
搜一页“露营装备”,取 5 条视频的详情和各自第一页评论,再展开点赞最多的 3 条评论下的回复
按本页生成时的价格计算。失败的调用不扣费。
在你的 AI 里用(MCP)
先接好 MCP 服务,然后直接说你要什么。智能体会自己找到这些接口、看清价格,再用你的余额调用。
可以这样说在视频号搜“露营装备”,挑点赞最多的 5 条视频查详情,各取第一页评论,再展开点赞最多的 3 条评论下的回复,整理成一张表:视频、评论或回复、点赞、IP 属地、时间。
智能体第一次调用 call 工具时发送的内容
{
"endpoint": "wechat_channels.videos.search",
"params": {
"query": "露营装备推荐"
},
"idempotency_key": "<新的 UUID>"
}