PHP调用B站创作中心API必须手动维护登录态Cookie(SESSDATA、bili_jct、buvid3)并实现WBI签名,老接口已下线;收益数据需模拟首页请求且前端加密,PHP纯HTTP无法稳定获取。

PHP 调用 B 站创作中心 API 需要先过登录态关
直接用 curl 或 file_get_contents 请求 B 站创作中心接口,99% 会返回 412 Precondition Failed 或跳转到登录页——因为所有创作中心数据(播放量、收益、稿件列表)都强依赖用户登录态,且是 Web 端 Cookie + CSRF Token 双校验,不是标准 OAuth2。
实操上没“合法公开 API”可调,所谓“API”实际是 B 站前端自己发的 xhr 请求,带 SESSDATA、bili_jct、buvid3 三个关键 Cookie,缺一不可:
-
SESSDATA:登录凭证,有效期通常 30 天,需手动从浏览器抓包获取(登录后访问https://api.bilibili.com/x/web-interface/nav响应里也有,但前提是 Cookie 已带上) -
bili_jct:CSRF token,每次提交表单或敏感请求必须携带,值在 HTML 源码或/x/frontend/fetch接口里可提取 -
buvid3:设备标识,相对稳定,可复用,但长期不用可能失效
PHP 里得用 cURL 手动维护 Cookie 文件或数组,不能靠 stream_context 简单设 header —— 否则 Set-Cookie 不会被自动回传,下个请求就掉登录态。
获取 UP 主视频播放数据:用 /x/space/wbi/arc/search 替代已下线的 /x/space/arc/list
B 站在 2023 年底把老接口 /x/space/arc/list 全量下线,现在必须走带 WBI 签名的新接口 /x/space/wbi/arc/search,否则返回 {"code":-400,"message":"请求错误"}。WBI 不是固定密钥,是按特定规则对参数排序+拼接+ md5,再截取部分字符生成签名字段 wts 和 w_rid。
立即学习“PHP免费学习笔记(深入)”;
PHP 实现要点:
- 参数必须按字典序排序(如
mid、ps、tid),再拼成key1=value1&key2=value2&wts=171xxxxxx形式 - 原始字符串末尾要加固定 salt(目前是
"1689b0910995a5f33d4e3c939b88873a"),再算 md5,取前 8 位小写为w_rid - 时间戳
wts必须是当前秒级时间,误差超过 300 秒会被拒 - 完整 URL 示例:
https://api.bilibili.com/x/space/wbi/arc/search?mid=123456789&ps=30&tid=0&pn=1&keyword=&order=pubdate&order_avoided=true&platform=web&web_location=1550104&wts=171xxxxxx&w_rid=xxxxxxxx
别信网上随手搜的“WBI 加密函数”,B 站会不定期更新 salt 和算法细节,建议直接扒 B 站前端 JS 里的 window._getWbiSign 实现逻辑,再用 PHP 重写。
收益数据根本不在公开 API 路径里,得模拟“创作中心首页”请求
播放量还能绕一绕,但收益(充电、广告、激励计划)完全不开放给第三方。B 站只在创作中心首页(https://member.bilibili.com/platform/home)用一个叫 /x/ugcpay-rank/center/monthly/report 的接口返回当月概览,但它有三重防护:
- 必须带
Referer: https://member.bilibili.com/,否则403 - 必须带
origin: https://member.bilibili.com - 响应是加密 JSON(实际是前端用 WebAssembly 解密),直接 curl 拿到的是乱码字符串,不是标准 JSON
目前没有稳定解密方案。有人试过逆向 WASM 模块,但 B 站每两周就更新一次加密逻辑;也有人用 Puppeteer 渲染页面后读 DOM,但服务器跑浏览器开销大、易被风控。PHP 单纯做 HTTP 请求这条路,到这里就断了。
容易被忽略的坑:IP 和 User-Agent 频控比想象中严
哪怕你 Cookie、WBI、Referer 全对,连续请求超过 5–8 次/分钟,就会触发 412 或返回空数据({"code":0,"data":{"list":[],"page":{"num":1,"size":30,"total":0}}})。这不是接口文档写的限制,是服务端行为策略:
- 同一 IP 下,不同账号共用一套频控,换
SESSDATA也没用 -
User-Agent必须和你抓包时浏览器一致(比如 Chrome 124,不能写成 curl/8.0) - 推荐加随机 delay(1.5–3.5 秒),并用
curl_setopt($ch, CURLOPT_HTTPHEADER, [...])显式设置Accept、Sec-Fetch-Dest等现代浏览器 header - 别用国内云服务器直连,B 站对阿里云、腾讯云出口 IP 有额外标记,封得更快
真要稳定跑,得准备至少 3–5 个真实账号轮换 Cookie,配合住宅代理池,而且得监控每次响应的 X-RateLimit-Remaining(如果有)或 Retry-After header —— 这些细节,文档里半个字都不会提。











