news 2026/9/20 4:27:22

OpenCLI B 站(bilibili)Adapter 开发站点记忆:域名、wbi 签名、已知接口与踩坑全指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenCLI B 站(bilibili)Adapter 开发站点记忆:域名、wbi 签名、已知接口与踩坑全指南
  • 开发工具
  • CLI
  • 人工智能
  • AI 应用
  • 浏览器控制
  • GUI 自动化

【免费下载链接】OpenCLI

Make Any Website into CLI & Use your logged-in browser by AI agent.

项目地址:https://gitcode.com/gh_mirrors/ope/OpenCLI
点击查看免费下载

本篇技术指南以 OpenCLI 仓库中skills/opencli-adapter-author/references/site-memory/bilibili.md这份站点记忆文档为核心骨架,结合仓库内clis/bilibili/下 30+ 个真实 adapter 与共享工具源码,系统讲解为 bilibili 编写 OpenCLI adapter 所需的全部站点知识:域名划分、默认鉴权策略、wbi 签名机制、常用 endpoint、字段约定与九类高频陷阱。读完本文,你可以掌握如何复用utils.js快速写出可验证、抗风控的 B 站 adapter,并理解opencli-adapter-authorskill 中"站点记忆"这一层知识资产的组织方式。

一、这份文档在 OpenCLI 中的作用

在 OpenCLI 的 adapter 编写技能opencli-adapter-author中,站点记忆(site memory)被设计为两层结构(见skills/opencli-adapter-author/references/site-memory.md):

  • in-repo 种子skills/opencli-adapter-author/references/site-memory/<site>.md,是手工编写 + PR 审核进入仓库的公共知识,多 agent 共享的第一批起点。目前已铺设eastmoney / xueqiu / bilibili / tonghuashun四个站点。
  • 本地工作目录~/.opencli/sites/<site>/,是 agent 每次跑 adapter 时自动累积的产物(endpoints.json/field-map.json/verify//fixtures//notes.md),不进 git、不进 PR。

bilibili.md就是 B 站这一站点在 in-repo 层的种子记忆。SKILL.md 的 Runbook 第 2 步明确要求:写 adapter 之前先读站点记忆,命中 endpoint 后不能直接跳去写代码,仍要跑 Step 5 endpoint 验证 + Step 7 字段抽查,因为 memory 可能过期或站点换版(verified_at超过 30 天视作过期,按冷启动重新侦察)。

该文档的固定结构(域名 → 默认鉴权 → 已知 endpoint → 字段 → 坑/陷阱 → 可参考的 adapter)正是所有站点记忆的统一 schema,本节文档是所有 B 站 adapter 开发的共同起点。

二、域名划分:六个域各司其职

B 站接口分散在多个子域名,写 adapter 前先明确请求落在哪个域,避免"接口 404"式的低级错误:

用途域名
主 APIapi.bilibili.com
个人主页 / 空间space.bilibili.com
登录 / 鉴权passport.bilibili.com
动态t.bilibili.com/api.vc.bilibili.com
直播api.live.bilibili.com

从源码可以印证这一点:clis/bilibili/utils.js中的apiGetbaseUrl固定为https://api.bilibili.com,所有主站接口都拼在这个域下;而直播接口独立在api.live.bilibili.com(记忆文档第 9 条陷阱也专门提醒了这点)。t.bilibili.com则用于动态页面的展示 URL——clis/bilibili/dynamic.js在输出动态条目时会把id_str拼成https://t.bilibili.com/${item.id_str}作为可跳转链接。

三、默认鉴权策略:COOKIE + browser

B 站 adapter 的默认鉴权策略是:

  • Strategy.COOKIE + browser: true:复用浏览器已登录的 cookie,在页面上下文内发请求。
  • 核心 cookieSESSDATA(登录态)与bili_jct(CSRF token)。部分写接口要求请求头带Referer + csrf
  • 未登录也能调多数读接口,但带有 wbi 签名要求(下文详述)。

查看仓库中 B 站 adapter 的声明,几乎全部是strategy: Strategy.COOKIE,例如clis/bilibili/user-videos.jsclis/bilibili/search.jsclis/bilibili/comments.jsclis/bilibili/me.jsclis/bilibili/history.js等。其中clis/bilibili/hot.js是少数例外——它不声明 strategy,直接用 pipeline 形式在www.bilibili.com页面内 fetch 热门接口,说明公开无签名接口可以不走 COOKIE 策略

写接口的 CSRF 处理在utils.jsapiPost中有完整实现:它在页面上下文中从document.cookie匹配bili_jct=([^;]+)取出 token,塞进 POST body 的csrf字段,并以application/x-www-form-urlencoded发送。值得注意的实现细节:B 站写接口可能返回 HTML 风控页(如 HTTP 412)而非 JSON,apiPost对此做了防护——先res.text()再尝试JSON.parse,解析失败则返回{ code: -1, message: "Non-JSON response (HTTP ...)" }的结构化错误,而不是让 JSON 解析直接崩溃。

此外utils.js还提供了getSelfUid(page):通过nav接口取data.mid作为当前登录用户 UID,拿不到就抛AuthRequiredErrorclis/bilibili/me.js正是用它配合/x/space/wbi/acc/info返回当前账号的名称、等级、硬币、粉丝数等资料。

四、核心机制:wbi 签名

4.1 签名规则

wbi 签名是 B 站 adapter 开发中最重要的机制,记忆文档给出了三条铁律:

  1. 凡 URL 含/wbi/的接口都要带w_rid + wts签名
  2. 签名算法依赖每日轮换的img_key / sub_key,从api.bilibili.com/x/web-interface/nav响应的wbi_img字段获取。
  3. 不要自己重新实现clis/bilibili/utils.js里的apiGet(page, path, { signed: true, params })已经封装好。

普通 cookie JSON 接口优先用page.fetchJson(url);站点级签名逻辑仍复用utils.js

4.2 源码级实现拆解

clis/bilibili/utils.js完整实现了 wbi 签名链,逐段拆解如下:

① 取 keygetWbiKeys(page)在页面上下文 fetchnav接口,从data.wbi_img.img_url / sub_url中截取文件名主干作为imgKey / subKeysplit('/').pop().split('.')[0])。

② 生成 mixin keygetMixinKey(imgKey, subKey)用内置的 64 项置换表MIXIN_KEY_ENC_TABimgKey + subKey重排,再截取前 32 个字符。这份置换表就硬编码在 utils.js 第 143-148 行。

③ 签名wbiSign(page, params)计算当前秒级时间戳wts,将所有参数(含wts)按 key 排序,每个值去除!'()*四个字符,拼成 query 后对query + mixinKey做 MD5 得到w_rid。这里有一个极其隐蔽的坑已由源码注释点明:B 站 wbi 校验要求空格编码为%20而不是+(URLSearchParams 默认行为),因此代码里做了.replace(/\+/g, '%20')——否则签名不匹配会导致 CORS 拦截,报TypeError: Failed to fetch

④ 发送apiGet(page, path, opts)opts.signed为真时先调用wbiSign对参数签名,再拼https://api.bilibili.com${path}?${qs}交给fetchJson在页面上下文以credentials: "include"请求。

4.3 缓存策略:不要每次请求都刷 nav

img_key / sub_key24 小时内有效,若每次请求都重新 fetchnav会被限频。记忆文档强调"utils.js 内部做了缓存"——写新 adapter 时直接复用即可,不要在业务代码里重复拉nav

五、已知 endpoint 清单

记忆文档整理了 12 条最常用的 B 站接口,按用途分组如下:

基础 / 鉴权类

  • GET api.bilibili.com/x/web-interface/nav— 登录态 + 拿 wbi key
  • GET api.bilibili.com/x/space/acc/info?mid=<uid>— 用户资料

视频类

  • GET api.bilibili.com/x/space/wbi/arc/search?mid=<uid>— 用户视频(需 wbi 签)
  • GET api.bilibili.com/x/web-interface/view?bvid=BV...— 视频详情

榜单类

  • GET api.bilibili.com/x/web-interface/popular?ps=20&pn=1— 热门
  • GET api.bilibili.com/x/web-interface/ranking/v2?rid=0— 排行

互动类

  • GET api.bilibili.com/x/v2/reply/wbi/main?type=1&oid=<aid>&mode=3— 评论(需 wbi)
  • GET api.bilibili.com/x/web-interface/search/all/v2?keyword=<q>— 综合搜索

用户数据类(需登录)

  • GET api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history?host_uid=<uid>— 用户动态(新版走api.bilibili.com/x/polymer/web-dynamic/v1/feed/space
  • GET api.bilibili.com/x/v2/history/cursor— 观看历史(需登录)
  • GET api.bilibili.com/x/v3/fav/folder/created/list-all— 收藏夹列表(需登录)

5.1 从源码看实际使用差异

对照仓库源码可以发现记忆文档与实际 adapter 之间有几个值得注意的对应关系:

  • 搜索接口clis/bilibili/search.js实际用的是/x/web-interface/wbi/search/type(带search_type: video | bili_user参数、走 wbi 签名),并支持type参数在视频搜索与用户搜索间切换。这与文档列出的/x/web-interface/search/all/v2是同一体系的另一形态——文档是"已知 endpoint 索引",具体 adapter 会按需选择。
  • 评论接口clis/bilibili/comments.js使用/x/v2/reply/main(顶层评论 + 置顶,wbi 签名)和/x/v2/reply/reply(某条评论下的楼中楼回复,参数root=<rpid>)。它还展示了 bvid → aid 的解析链路:先调/x/web-interface/viewaid,因为 reply 系列接口的oid需要的是 aid 而非 bvid。
  • 历史接口clis/bilibili/history.js实际调用/x/web-interface/history/cursor,与文档记录一致,且ps上限是 30(不是 50),并支持type: archive过滤。
  • 收藏接口clis/bilibili/favorite.js先调/x/v3/fav/folder/created/list-all?up_mid=<uid>拿收藏夹列表,默认取第一个收藏夹的 id,再调/x/v3/fav/resource/listps上限 40)拉取具体内容。
  • 动态接口换版clis/bilibili/dynamic.js已经使用新版/x/polymer/web-dynamic/v1/feed/all(当前登录用户的动态流),与文档"新接口走x/polymer/web-dynamic/v1/feed/space"的提示一致,老的dynamic_svr已废弃。

这些差异说明:站点记忆是索引不是权威,写 adapter 时必须回到源码或实际抓包确认 endpoint 形态。

六、字段约定

B 站接口字段基本人类可读,核心代号已在skills/opencli-adapter-author/references/field-conventions.md的 bilibili 节登记:

字段含义
mid用户 UID
aid / bvid视频 ID(av 号 / bv 号)
cid视频分 P ID
uname / upnameup 主昵称
view / danmaku / reply / favorite / coin / share / like各类计数
pubdate / ctime发布 / 创建时间(秒级 unix)

注意miduid是同一回事(陷阱第 2 条):接口参数不统一,mid=居多,个别接口要求host_mid=。仓库中resolveUid(utils.js)统一了这一差异:纯数字输入直接当作 mid,非数字输入则走wbi/search/typesearch_type: bili_user)按用户名搜索取第一个结果的mid,搜不到抛EmptyResultError

时间字段统一是秒级 Unix 时间戳,adapter 输出前需自行格式化——例如user-videos.jsnew Date(item.created * 1000).toISOString().slice(0, 10)comments.jsnew Date(ctime * 1000).toISOString().slice(0, 16)

七、坑 / 陷阱:九条高频踩坑记录

记忆文档的"坑 / 陷阱"节是整份文档最浓缩的实战价值所在,逐条展开如下:

  1. wbi 签名缓存img_key / sub_key:24 小时内有效,每次请求都重新 fetchnav会被限频。utils.js 内部已做缓存,直接复用apiGet({ signed: true })即可。

  2. miduid一回事:接口参数不统一,mid=居多,个别接口要host_mid=。写 adapter 前先确认目标接口的参数名。

  3. 视频 ID 有两种aid(老数字 av 号)与bvid(BV1xxx 格式)。视频详情要用bvid;而评论等部分接口的oid需要aid,需要先经 view 接口做一次 bvid → aid 转换(见comments.js的实现)。

  4. ps=最大 50(popular / ranking):超过 50 需多发几页再拼接。仓库中user-videos.jsMath.min(Number(limit), 50)做上限钳制,history.js用 30、favorite.js用 40——各接口上限不一致,写前查证

  5. 动态接口换版:老的dynamic_svr已废弃,新接口走x/polymer/web-dynamic/v1/feed/space,写新 adapter 直接用新接口。

  6. 评论分页靠next游标,不是页号。comments.js对楼中楼回复也是用root: <rpid>定位,而不是 page 参数。

  7. B 站限频-352 风控:短时间高频调用会被拦截,adapter 层应加约 500ms 间隔。这是"验证能过但生产环境挂"的典型场景,批量抓取时务必控制节奏。

  8. 搜索要先 "cold start":空 cookie 的 session 第一次搜索会返回 412,需要先访问首页拿到buvid3cookie 再搜。这与hot.jspipeline 第一步先navigate: 'https://www.bilibili.com'的做法互相印证——在页面上下文 fetch 天然自带 cold-start 过程。

  9. 直播接口在api.live.bilibili.com,不在主 API 域。这与第二节的域名表一一对应。

7.1 补充源码层的额外防御

除文档九条外,utils.js还体现了两类值得复用的防御性设计:

  • 错误路由requireOkPayload(payload, label)检查{ code, message, data }信封结构,code !== 0时按isAuthLikeBilibiliError判定——-101 / -111 / -403或 message 匹配csrf / 登录 / 账号 / 权限 / forbidden / permission / login的抛AuthRequiredError,其余抛CommandExecutionError,保证登录过期不会被误报为普通执行错误。
  • 输入校验parsePageArg--page选集序号做严格校验(缺省返回 null 不下钻;非正十进制整数抛ArgumentError);resolveBvid支持 BV 号、bilibili.com/video/BV...URL、以及b23.tv短链三种输入形态,短链解析带 4 秒超时。

八、可参考的 adapter 索引

记忆文档按功能列出了 B 站 adapter 的模板对照表。结合仓库中 30 个文件的实际分布,完整索引如下:

模板类型参考文件
用户资料 / 视频列表clis/bilibili/user-videos.js/me.js
视频详情 / 字幕clis/bilibili/download.js/subtitle.js
评论clis/bilibili/comments.js
搜索clis/bilibili/search.js
热门 / 排行clis/bilibili/hot.js/ranking.js
动态clis/bilibili/dynamic.js
关注clis/bilibili/following.js
收藏clis/bilibili/favorite.js
观看历史clis/bilibili/history.js
创作者数据clis/bilibili/creator-stats.js
关系操作clis/bilibili/follow.js/unfollow.js/relation.js
视频摘要 / 综合信息clis/bilibili/summary.js/video.js/feed.js

通用工具clis/bilibili/utils.js。新 adapter 第一行就应import { apiGet, fetchJson } from './utils.js',不要重写签名与请求逻辑。

8.1 两个典型 adapter 的写法拆解

user-videos.js(标准 COOKIE + wbi 读接口范式):声明site: 'bilibili', name: 'user-videos', strategy: Strategy.COOKIE,参数含 positional 的uid(支持 UID 或用户名)、limitorderpubdate / click / stow)、page。func 内先resolveUid归一化用户,再apiGet('/x/space/wbi/arc/search', { params: { mid, pn, ps, order }, signed: true }),从payload.data.list.vlist映射出 rank / title / plays / likes / date / url 六列,与columns声明完全对齐。

hot.js(pipeline 范式,无需 wbi):不写 func,而是用 pipeline 声明navigate → evaluate(fetch popular) → map → limit。第一步先导航到www.bilibili.com完成 cold-start,然后在页面上下文直接 fetch/x/web-interface/popular?ps=...&pn=1,无需任何签名。这印证了记忆文档的判断——热门这类公开接口不必走 wbi,但要在页面上下文执行以携带会话。

九、写新 adapter 时的落地步骤

结合本记忆文档与opencli-adapter-author的 Runbook,为 B 站新增 adapter 的推荐路径是:

  1. 读记忆:先读本文档(in-repo 种子)与~/.opencli/sites/bilibili/(本地累积)。命中 endpoint 后仍要跑 endpoint 验证 + 字段抽查。
  2. 定策略:B 站绝大多数接口走Strategy.COOKIE + browser: true;纯公开榜单类可参考hot.js的 pipeline 写法。
  3. 复用 utilsimport { apiGet, fetchJson, resolveUid, getSelfUid } from './utils.js'。需要 wbi 的接口传signed: true;普通 cookie JSON 接口用fetchJsonpage.fetchJson
  4. 核对字段:对照field-conventions.md的 bilibili 节,时间戳记得 ×1000 转 Date;注意mid / uid命名差异与aid / bvid的使用场景。
  5. 写 typed errorcode !== 0时交给requireOkPayload路由,登录态问题抛AuthRequiredError,空结果抛EmptyResultError,不要return []或塞 sentinel 行(详见skills/opencli-adapter-author/references/typed-errors.md)。
  6. 验证与回写opencli browser verify bilibili/<name>通过后用--write-fixture生成种子并手改patterns / notEmpty / rowCount;肉眼比对网页值无误后,把 endpoint / field-map / notes 回写~/.opencli/sites/bilibili/——记忆是每轮滚动的资产,越滚越厚。

十、与 skill 其他参考文件的配合关系

本记忆文档不是孤立的,它与opencli-adapter-author技能体系的其他参考文件形成闭环:

  • skills/opencli-adapter-author/references/site-memory.md:站点记忆两层结构总览,bilibili.md就是其中 in-repo 种子的实例。
  • skills/opencli-adapter-author/references/field-conventions.md:字段代号解码表,bilibili 节即本文第六节内容的出处。
  • skills/opencli-adapter-author/references/adapter-template.md:adapter 三段式写法(declaration / args / func)与 COOKIE 骨架。
  • skills/opencli-adapter-author/references/typed-errors.md:5 类 typed error 的落点与反模式。
  • skills/opencli-adapter-author/references/strategy-selection.md:为什么 COOKIE_API 优于 PAGE_FETCH/INTERCEPT 的契约模型与实测维护成本。

阅读顺序建议:先SKILL.md建立整体流程,再读本记忆文档快速进入 B 站上下文,写代码时回到adapter-template.mdutils.js源码对照。


综上,bilibili.md虽是一份篇幅有限的"站点记忆"卡片,但浓缩了 B 站 adapter 开发最关键的域名、鉴权、签名、接口与陷阱知识;结合仓库源码后,它足以支撑从零写出一条健壮的 B 站 adapter。对后续 agent 而言,这份记忆的增量价值在于:先查记忆、再验 endpoint、后写 adapter、最后回写记忆——这是 OpenCLI 站点适配器生态能持续滚动的根本机制。

  • 开发工具
  • CLI
  • 人工智能
  • AI 应用
  • 浏览器控制
  • GUI 自动化

【免费下载链接】OpenCLI

Make Any Website into CLI & Use your logged-in browser by AI agent.

项目地址:https://gitcode.com/gh_mirrors/ope/OpenCLI
点击查看免费下载

相关推荐

上一篇:Riva-Translate-4B-Instruct-v2聊天模板深度解析:自定义翻译任务技巧
下一篇:RPA-Python与pytest-cinderclient集成:打造高效OpenStack Cinder测试自动化方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 4:26:27

2025自建Git服务选型与部署:Gitea、GitLab、Bitbucket对比

1. 自建Git服务前&#xff0c;先想清楚这几个核心问题做技术选型最忌讳一上来就比功能清单。我在帮团队和客户搭建自建Git服务时&#xff0c;遇到最多的场景就是&#xff1a;几个人临时组个项目&#xff0c;发现GitHub私有仓库名额不够用&#xff0c;或者公司有代码保密要求&am…

作者头像 李华
网站建设 2026/9/20 4:26:03

Python解析docx托福词表:正则切片、SQLite落库与Anki导出

简介&#xff1a;红宝书托福词汇是面向托福备考者与英语进阶学习者的词汇速查文档&#xff0c;针对词汇量大、释义分散、缺乏系统归类的痛点&#xff0c;按语言、学术、社会、文化等主题梳理核心词汇。压缩包内为1个docx文件&#xff0c;体积约71KB&#xff0c;以单词加词性与中…

作者头像 李华
网站建设 2026/9/20 4:25:48

基于投影寻踪-博弈论-云模型的滑坡风险评价MATLAB实现

简介&#xff1a;这份资料围绕MATLAB实现投影寻踪博弈论-云模型的滑坡风险评价展开&#xff0c;面向地质灾害研究者、城市规划与环境科学从业者及灾害应急管理人员&#xff0c;提供从数据采集与预处理、投影寻踪博弈论建模、云模型处理到风险评估输出的一体化项目范例。资源包仅…

作者头像 李华
网站建设 2026/9/20 4:24:53

5G相控阵仿真全解析:从波束成形原理到工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 4:24:12

RapidOCR 文字识别入门:三步跑通你的第一个 OCR 任务

RapidOCR 文字识别入门&#xff1a;三步跑通你的第一个 OCR 任务 【免费下载链接】RapidOCR &#x1f4c4; Awesome OCR multiple programing languages toolkits based on ONNX Runtime, OpenVINO, MNN, PaddlePaddle, TensorRT and PyTorch. 项目地址: https://gitcode.com…

作者头像 李华