Bilibili Operations Skill (All-in-One)
Merged from 6 original skills: bilibili-cookie / bilibili-comment / bilibili-auto-comment / bilibili-message / bilibili-daily-report / bilibili-video-download.
Skill-First Hard Rule
For any Bilibili task (download, comment, private message, API call, daily report, danmaku), the first step is always skill_view(name='bilibili'). Do not run yt-dlp bare, do not write scripts that hard-call APIs, and do not directly force your way into the browser. GK has repeatedly corrected the issue of "not using the skill" across multiple sessions.
All Bilibili requests (downloads, API calls, comments) must include a Cookie, even for standard quality; without it, you will get a 412 error.
Feature Routing
| Task | Detailed Docs | Script / Quick Command |
|---|---|---|
| Cookie acquisition/refresh (QR login) | references/cookie-login.md | Inline docs in flow (complete Python code) |
| Search videos/users (WBI) | references/cookie-login.md | `scripts/bili_wbi_search.py "" [video |
| Video download | references/video-download.md + references/cookie-login.md yt-dlp section | scripts/cookie_to_netscape.py → yt-dlp |
| Post/reply/delete comments | references/comment-api.md | scripts/post_reply.sh <BVID> <message> [root_rpid] [parent_rpid] |
| Auto-comment bot | references/auto-comment.md | scripts/bili_auto_comment.py --count 30 --interval 600 |
| Send private messages | references/message-browser.md | Browser workflow, see docs (api.vc is risk-controlled, cannot be pure API) |
| Hot daily report PPT | references/daily-report.md | bash ~/.hermes/skills/bilibili/scripts/run_daily.sh |
| Full feature verification ("test if skill works") | references/verification.md | Run all 10 items per docs, minimal side effects |
| Danmaku scraping | references/danmaku-protobuf.md | See docs (protobuf parsing) |
| Hot stream / ranking API | references/APIv2.popular.md, references/APIv2.ranking.md | Public endpoints, no login required |
| Comment API fields / error codes | references/comment-api.md (appendix includes original reply API reference) | — |
Shared Foundation (Must-Read for All Features)
Cookie
- File:
~/.bilibili-cookie, single-line formatSESSDATA=xxx; bili_jct=xxx; DedeUserID=xxx - SESSDATA=login credential (required for all login-required endpoints); bili_jct=csrf token (must include
csrf=xxxin POST); DedeUserID=user mid - Validity: approximately 30 days. If any endpoint returns
-101or nav shows not logged-in → Cookie expired, re-scan QR code according to references/cookie-login.md. Proactively inform GK "Cookie has expired, need to re-scan QR", don't wait for them to figure it out - Before any cookie-required operation, first hit the nav endpoint to quickly verify
- yt-dlp's --cookies only accepts Netscape format: first run
python3 ~/.hermes/skills/bilibili/scripts/cookie_to_netscape.py(outputs /tmp/bili_netscape_cookie.txt) - The currently logged-in account is determined by the nav endpoint (
x/web-interface/nav), do not hardcode a specific UID
Request Conventions
- UA: Always use the full Chrome string:
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36(short UA strings are risk-controlled) - POST: Must include
Referer: https://www.bilibili.com/video/{BVID}+Origin: https://www.bilibili.com+csrf - Search endpoints must use the
/x/web-interface/wbi/search/typepath (non-wbi paths return HTML error pages)
API Reliability Table (Server IP Measured)
| Endpoint | Status |
|---|---|
view (BVID→AID/CID) | Stable |
wbi/search/type (video/bili_user, no wbi signing required) | Available |
reply/main / reply/add / reply/del | Available |
popular / ranking/v2 | Available, public, no login required |
space/arc/search | -799 rate-limited, do not use |
search/type (without wbi path) | Risk-controlled, returns HTML error page |
api.vc.bilibili.com (private messages) | Fully risk-controlled, must go through browser UI |
Critical Error Codes
| Code | Meaning | Action |
|---|---|---|
| -101 | Not logged-in / Cookie expired | Re-scan QR code to login |
| -509 | Request too frequent | Wait 5–10 seconds and retry |
| -799 | Server IP rate-limited | Switch endpoint path; retrying is ineffective |
| -635 | Video comments disabled | Skip |
| -637 | Sensitive word | Skip / edit text |
| 12014 | Daily comment send limit reached | Stop the script and wait 24 hours (not a few hours); do not restart with short intervals to probe |
| 412 | Download without Cookie / risk control | Use Netscape Cookie or API method |
| 12061 | UP master closed comment section | Skip |
Feature Highlights
Video Download
Prefer yt-dlp + Netscape Cookie (can unlock 1080P). If yt-dlp gets 412, switch to API method: playurl with fnval=0&platform=html5 gets durl direct mp4 links (dash separate streams return 403 without login), CDN download must include Referer: https://www.bilibili.com. qn: 16=360p 32=480p 64=720p 80=1080p.
Comments
oid is avid, not bvid; convert via the view endpoint first. First-level comments root=0 parent=0; replies include root+parent. To find a user's latest video: wbi search with search_type=video&order=pubdate and take the first result. -509: wait 5-10 seconds.
Auto-Comment Bot
--count 30 --interval 600 (100/300 triggers 12014). Before starting, check for residual processes with ps aux | grep bili_auto_comment. Add random delay of 1–3 seconds per comment. For persistent background, use terminal(background=true) or crontab, not nohup/disown. Stop immediately on large-scale 12014.
Private Messages
api.vc is unavailable from both server IP curl and page XHR. The only solution: inject Cookie into browser → go to user's space page, click "Send Message" → input into .brt-editor (must dispatch input event) → click send using [class*="_MessageSendBox__SendBtn_"] fuzzy match. Unfollowed users are limited to 1 message (not an error).
Daily Report
bash /home/ubuntu/bilibili-daily/run_daily.sh one-command full flow, no Cookie needed, takes about 15 seconds. Template source is in this skill's scripts/; data and PPT output are in /home/ubuntu/bilibili-daily/. pptxgenjs pitfalls: color without #, option object must be newly created each time.
Global Pitfalls
- Always include Cookie in Bilibili requests, otherwise 412.
- QR code must be saved as a PNG file for GK to scan (/home/ubuntu/Downloads/bilibili_qrcode.png), never print ASCII QR codes.
- Search/title fields contain
<em class="keyword">highlight tags; clean them withre.sub(r'<[^>]+>', '', title). - When 412/403 occurs, add buvid3/buvid4 etc. Cookie fields to handle risk control.
- For popular/ranking pagination, wait at least 1 second between pages to avoid -799.
- For full per-feature pitfalls, see each references document.