Files
libilibili/README.md
T
2026-07-18 12:44:28 -07:00

4.0 KiB
Raw Blame History

libilibili

异步 Rust Bilibili Web/直播 API 库,依据 feliscafra/Bilibili-Live-API 的接口、鉴权与 WebSocket 文档实现。

功能

  • 公开 GET、WBI GET、Cookie GET、带 CSRF 的 Cookie POST,以及 WBI+POST。
  • 从 /x/web-interface/nav 自动刷新和缓存 WBI key;参数排序、清洗、percent-encode、MD5 签名均在库内完成。
  • 登录 Cookie 存在内存;状态变更请求自动写入 csrf 与 csrf_token(取自 bili_jct)。
  • 高层分组:直播间/分区/播放/礼物/勋章、视频、空间与关系、评论、搜索。
  • 默认 websocket feature:直播弹幕认证、心跳和 JSON/zlib/brotli 协议包解析,并只连接 *.chat.bilibili.com。
  • 使用通用请求方法覆盖参考文档中尚未提供快捷封装的低频或易变端点。

使用

[dependencies]
libilibili = "0.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
use libilibili::{Client, Credentials};

#[tokio::main]
async fn main() -> Result<(), libilibili::Error> {
    let anonymous = Client::anonymous()?;
    let room = anonymous.live().room_detail(5050).await?; // 自动 WBI
    println!("{room:#}");

    let auth = Credentials::from_cookie_header("SESSDATA=...; bili_jct=...");
    let client = Client::with_credentials(auth)?;
    client.video().like(170001, true).await?; // 自动 csrf + csrf_token
    Ok(())
}

不需要 WebSocket:

libilibili = { version = "0.1", default-features = false }

通用端点调用与鉴权

鉴权类型 方法
Public GET client.get(url, query)
WBI GET client.get_wbi(url, query)
Cookie POST client.post_form(url, form)
Cookie + WBI POST client.post_form_wbi(url, query, form)

query/form 是 Vec<(String, String)>;响应的 data 为泛型,快捷方法默认保留为 serde_json::Value,防止上游新增字段时信息丢失。

# use libilibili::Client;
# async fn example(client: Client) -> Result<(), libilibili::Error> {
let history: serde_json::Value = client.get(
    "https://api.live.bilibili.com/xlive/web-room/v1/dM/gethistory",
    vec![("roomid".into(), "5050".into()), ("room_type".into(), "0".into())],
).await?;
# Ok(()) }

弹幕 WebSocket

use libilibili::{Client, Credentials, websocket::LiveWebSocket};

# async fn example() -> Result<(), libilibili::Error> {
let credentials = Credentials::from_cookie_header("SESSDATA=...; bili_jct=...; buvid3=...");
let client = Client::with_credentials(credentials)?;
let mut ws = LiveWebSocket::connect(&client, 5050).await?;
ws.heartbeat().await?; // 应约每 30 秒调用
while let Some(event) = ws.next_event().await? { println!("{event:?}"); }
# Ok(()) }

原始帧抓取

libilibili-capture 可连接一个已登录的直播间,并将收到的原始 WebSocket 二进制帧 写为 stdout 的 JSON Lines;连接状态与心跳日志只写入 stderr。每条输出含完整 frame_base64,以及未解压协议包的版本、操作码和 body_base64,便于离线复现协议 解析。

cargo run --bin libilibili-capture -- \
  --cookie 'SESSDATA=...; bili_jct=...; buvid3=...' \
  --room-id 5050 \
  --seconds 120 \
  > frames.jsonl

更安全的方式是通过标准输入提供 Cookie:

printf '%s' "$BILI_COOKIE" | cargo run --bin libilibili-capture -- \
  --cookie-stdin --room-id 5050 --seconds 120 > frames.jsonl

Cookie 不会被工具输出,但命令行参数可能被同机其他用户读取;在共享机器上应使用 --cookie-stdin、受限权限的启动器或 secret 管理器注入 Cookie。

安全边界

本库不自动化密码、验证码、二维码或 OAuth 登录,也不尝试绕过风控。通过 Bilibili 正常登录取得会话后,使用环境变量或 secret store 注入 SESSDATA/bili_jct;绝不要提交或记录这些值。-352 代表风控/上下文限制,不等价于接口下线。