[BUG] B站评论爬取只输出 3 条:/x/v2/reply/wbi/main 需 WBI 签名,失败后翻页循环提前终止
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 82/100
Research direction
Read media_platform/bilibili/client.py, starting with get_video_comments() and the pagination and retry logic in get_video_all_comments(). The issue reports that the WBI endpoint returns -403 while the unsigned endpoint paginates successfully; verify the request arguments and signature behavior against the existing get() method. Done means comments continue across pages and stop at the requested maximum.
Written by the indexing model from the issue text.
Description
问题检查清单
- 我已经仔细阅读了项目使用过程中的常见问题汇总
- 我已经搜索并查看了已关闭的 issues(#956 是"置顶评论遗漏",与本文症状不同)
- 我确认这不是由于滑块验证码、Cookie 过期、平台风控导致的(风控是另一个独立现象,见文末附注)
问题描述
BilibiliClient.get_video_comments() 使用的接口 /x/v2/reply/wbi/main 需要 WBI 签名。当签名不可用或失效时,接口返回 code=-403 访问权限不足,导致:
request()中if data.get("code") != 0: raise DataFetchError(...)抛异常get_video_all_comments()捕获后重试 3 次并置is_end = True- 整个评论翻页循环在第 1 页就终止
实际表现:某视频评论总数 850 条,但只落盘 3 条(即第一页 replies 的前 3 条),且日志无明确报错,爬虫正常结束。
复现步骤
uv run main.py \
--platform bili \
--type detail \
--specified_id BV18NzvB5EZu \
--get_comment yes \
--save_data_option jsonl
该视频 aid=115961164271702,评论总数 850(可通过 https://api.bilibili.com/x/v2/reply/count?type=1&oid=115961164271702 查得)。
结果:jsonl 只有 3 条评论,而非 850 条。
根本原因验证
同一时间、同一 aid,对比两个端点:
GET /x/v2/reply/wbi/main?oid=115961164271702&mode=0&type=1&ps=20&next=0
→ {"code":-403,"message":"访问权限不足"}
GET /x/v2/reply/main?oid=115961164271702&mode=0&type=1&ps=20&next=0
→ {"code":0,"data":{"replies":[20 条],"cursor":{"is_end":false,"next":2,"all_count":850}}}
/x/v2/reply/main 无需 WBI 签名,每页稳定返回 20 条,且 cursor.next 可正常翻页(实测连续 6 页均 20 条,未达 end)。
相关代码
media_platform/bilibili/client.py(commit d6f7c5b):
# L266 附近
async def get_video_comments(self, video_id, order_mode=CommentOrderType.DEFAULT, next=0):
uri = "/x/v2/reply/wbi/main" # ← 需要 WBI 签名
post_data = {"oid": video_id, "mode": order_mode.value, "type": 1, "ps": 20, "next": next}
return await self.get(uri, post_data)
注意 get() 默认 enable_params_sign=True,会对参数做 WBI 签名。
get_video_all_comments() 中的异常处理会直接终止翻页(L293-L307 附近):
for attempt in range(max_retries):
try:
comments_res = await self.get_video_comments(video_id, CommentOrderType.DEFAULT, next_page)
break
except DataFetchError as e:
... # 重试 3 次后
is_end = True
break
if not comments_res:
break # ← 直接跳出 while 循环
建议修复
方案 A(推荐):改走非 wbi 端点,并显式关闭签名
async def get_video_comments(self, video_id, order_mode=CommentOrderType.DEFAULT, next=0):
uri = "/x/v2/reply/main"
post_data = {"oid": video_id, "mode": order_mode.value, "type": 1, "ps": 20, "next": next}
return await self.get(uri, post_data, enable_params_sign=False)
⚠️ 关键:必须显式
enable_params_sign=False,否则get()仍会签名,改端点等于没改。
方案 B:保留 wbi/main,修复 get_wbi_keys() 的密钥刷新逻辑。
方案 C(兜底):在 get_video_comments 内对 -403 做 fallback 到非 wbi 端点。
修复后验证
用 monkey-patch 实施方案 A 后,本地验证:
get_video_all_comments(max_count=50)
callback: +20 (total 20)
callback: +20 (total 40)
callback: +10 (total 50) ← 正确翻页并按 max_count 截断
TOTAL: 50
运行环境
- 操作系统: Windows 11
- Python 版本: 3.13
- MediaCrawler commit:
d6f7c5b(2026-08-14) - 是否使用 IP 代理: 是(Clash 本地代理;直连同样复现,非影响因素)
- 目标平台: B站(Bilibili)
- 依赖管理工具: uv
- 浏览器模式: 标准 playwright(非 CDP)
- httpx: 0.28.1
附注:另一个独立问题(不属本 Issue)
当请求频率较高时,/x/v2/reply/main 也会返回 code=-352(风控)。这是服务端限流,与 WBI 签名无关;建议降低 CRAWLER_MAX_SLEEP_SEC 或加随机抖动。
排障时请先确认返回的 code 是 -403(本 Issue)还是 -352(风控),两者现象相似但根因不同。
- Dominant language
- Python
- Stars
- 70.7k
- Forks
- 13.4k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 3
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from NanmiCoder/MediaCrawler
-
Difficulty 5/5 Over a week Newbie friendliness 15/100
NanmiCoder/MediaCrawler#995 ·
-
Difficulty 5/5 Over a week Newbie friendliness 12/100
NanmiCoder/MediaCrawler#992 · 1 comment ·
-
bug
Difficulty 3/5 Half a day Newbie friendliness 60/100
NanmiCoder/MediaCrawler#990 · 1 comment ·
-
小红书 creator 爬取失败Openbug
Difficulty 3/5 1-2 days Newbie friendliness 65/100
NanmiCoder/MediaCrawler#985 ·
-
[问题]Openquestion
Difficulty 5/5 Over a week Newbie friendliness 25/100
NanmiCoder/MediaCrawler#984 · 1 comment ·
All issues in NanmiCoder/MediaCrawler
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
django-cms/djangocms-frontend#413 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
facebookresearch/xformers#1417 ·
-
question
Difficulty 1/5 Under an hour Newbie friendliness 68/100
vllm-project/vime#524 ·
Maintainers usually reply within 7 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 73/100
FinanceFlash/unvibecode#675 ·
Maintainers usually reply within 1 day
-
WOPI editor page is scrollable by a few pixels, which breaks scrolling in the document (Firefox)Open
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
suitenumerique/drive#969 ·
Maintainers usually reply within 1 day