B站视频列表与详情数据API调用完全指南
一、前置准备:开发者认证与环境配置
1.1 开放平台开发者认证(官方接口必备)
注册与认证:访问开放平台,完成账号注册后,进入"开发者中心"提交企业或个人开发者认证材料,审核通过后获得开发者资质。
创建应用:在开发者中心创建应用,填写应用名称、用途、场景等信息,获取核心凭证——
AccessKeyId和AccessKeySecret(后续签名认证需用到)。
1.2 环境与工具准备
开发语言:Python(推荐,拥有丰富的HTTP请求库如requests)、Java、JavaScript等均可。
调试工具:Apifox、Postman(快速验证接口参数与响应)、浏览器开发者工具(分析Web端接口交互)。
依赖库:Python环境需安装requests库(
pip install requests),用于发送HTTP请求;若需处理JSON数据,可使用内置json库。
二、核心API详解:视频列表与详情获取
2.1 开放平台官方接口
2.1.1 视频列表查询接口
接口地址:
https://member.bilibili.com/arcopen/fn/archive/viewlist请求方式:GET
认证方式:签名版本2.0(需添加公共请求头)+ Access-Token
请求参数(URL参数):
参数名 | 必传 | 类型 | 说明 | 备注 |
|---|---|---|---|---|
pn | 是 | int | 页码 | 最小为1 |
ps | 是 | int | 每页数量 | 最小1,最大50 |
status | 否 | string | 稿件状态 | 可选值:all(全部)、is_pubing(发布中)、pubed(已发布)、not_pubed(未发布),默认查询全部 |
请求头(核心公共请求头):
请求头字段 | 说明 |
|---|---|
X-Bili-Accesskeyid | 开放平台获取的AccessKeyId |
X-Bili-Signature-Version | 签名版本,固定为2.0 |
X-Bili-Signature-Method | 签名算法,固定为HMAC-SHA256 |
X-Bili-Timestamp | 当前时间戳(秒级) |
X-Bili-Signature-Nonce | 随机字符串(需保证唯一性) |
X-Bili-Content-Md5 | 请求体MD5值(GET请求无请求体时为d41d8cd98f00b204e9800998ecf8427e) |
Authorization | 签名结果(计算方式见2.3节) |
Access-Token | 用户授权凭证 |
响应参数(核心字段):
参数名 | 类型 | 说明 |
|---|---|---|
resource_id | string | 稿件ID(可用于查询视频详情) |
title | string | 视频标题 |
cover | string | 封面图片URL |
video_info.duration | int | 视频时长(秒) |
video_info.share_url | string | 视频播放页链接 |
ctime/ptime | int | 创建时间/发布时间(UTC时间戳) |
2.1.2 视频详情查询接口
接口地址:
https://member.bilibili.com/arcopen/fn/archive/view请求方式:GET
认证方式:与视频列表接口一致(签名2.0+Access-Token)
请求参数(URL参数):
参数名 | 必传 | 类型 | 说明 |
|---|---|---|---|
resource_id | 是 | string | 稿件唯一ID(从视频列表接口获取) |
2.2 Web端实用接口(非官方)
2.2.1 公开视频详情接口
接口地址:
https://api.bilibili.com/x/web-interface/wbi/view请求方式:GET
认证方式:Cookie认证(需携带sessdata,用于访问需登录可见的视频)
请求参数(URL参数):
参数名 | 必传 | 类型 | 说明 |
|---|---|---|---|
bvid | 可选(二选一) | string | 视频BV号(如BV1MW421X7gM) |
aid | 可选(二选一) | num | 视频AV号(如123456) |
基础信息:bvid/aid(视频编号)、title(标题)、pic(封面URL)、duration(总时长);
UP主信息:owner(包含mid、name等);
数据统计:stat(包含play播放量、comment评论数、like点赞数等);
其他信息:desc(视频简介)、pubdate(发布时间戳)、pages(分P列表)。
2.2.2 UP主公开视频列表接口
接口地址:
http://space.bilibili.com/ajax/member/getSubmitVideos请求方式:GET
认证方式:可选Cookie认证(获取需登录可见的视频)
请求参数(URL参数):
参数名 | 必传 | 类型 | 说明 |
|---|---|---|---|
mid | 是 | num | UP主用户ID(从用户主页URL获取) |
pn | 否 | int | 页码,默认1 |
ps | 否 | int | 每页数量,默认10 |
三、关键技术:签名认证实现(官方接口必备)
3.1 签名计算规则
收集所有请求参数(包括URL参数和公共参数),不包含请求头中的字段;
将参数按Key的ASCII码升序排序;
将排序后的参数拼接为"key1=value1&key2=value2"的字符串;
将拼接后的字符串与AccessKeySecret(开放平台获取)拼接,使用HMAC-SHA256算法计算哈希值,得到签名结果(小写);
将签名结果放入请求头的Authorization字段。
3.2 Python签名实现代码
import hmac
import hashlib
import time
import uuid
def calculate_signature(params, access_key_secret):
# 1. 按Key升序排序
sorted_params = sorted(params.items(), key=lambda x: x[0])
# 2. 拼接参数字符串
param_str = "&".join([f"{k}={v}" for k, v in sorted_params])
# 3. HMAC-SHA256计算签名
hmac_obj = hmac.new(access_key_secret.encode("utf-8"), param_str.encode("utf-8"), hashlib.sha256)
signature = hmac_obj.hexdigest()
return signature
# 示例:构造请求参数与请求头
access_key_id = "你的AccessKeyId"
access_key_secret = "你的AccessKeySecret"
params = {
"pn": 1,
"ps": 10,
"status": "all"
}
# 生成必要的公共参数
timestamp = str(int(time.time()))
nonce = str(uuid.uuid4().int) # 随机字符串
content_md5 = "d41d8cd98f00b204e9800998ecf8427e" # GET请求无请求体时固定此值
# 计算签名
signature = calculate_signature(params, access_key_secret)
# 构造请求头
headers = {
"X-Bili-Accesskeyid": access_key_id,
"X-Bili-Signature-Version": "2.0",
"X-Bili-Signature-Method": "HMAC-SHA256",
"X-Bili-Timestamp": timestamp,
"X-Bili-Signature-Nonce": nonce,
"X-Bili-Content-Md5": content_md5,
"Authorization": signature,
"Access-Token": "你的用户授权Token",
"Content-Type": "application/json"
}四、实战示例:完整API调用流程
4.1 官方接口示例:查询授权用户视频列表
import requests
from typing import Dict, Any
# 复用3.2节的签名计算函数
def calculate_signature(params, access_key_secret):
sorted_params = sorted(params.items(), key=lambda x: x[0])
param_str = "&".join([f"{k}={v}" for k, v in sorted_params])
hmac_obj = hmac.new(access_key_secret.encode("utf-8"), param_str.encode("utf-8"), hashlib.sha256)
return hmac_obj.hexdigest()
def get_authorized_video_list(access_key_id: str, access_key_secret: str, access_token: str, pn: int = 1, ps: int = 10) -> Dict[str, Any]:
url = "https://member.bilibili.com/arcopen/fn/archive/viewlist"
# 构造请求参数
params = {
"pn": pn,
"ps": ps,
"status": "all"
}
# 生成公共参数与签名
timestamp = str(int(time.time()))
nonce = str(uuid.uuid4().int)
content_md5 = "d41d8cd98f00b204e9800998ecf8427e"
signature = calculate_signature(params, access_key_secret)
# 构造请求头
headers = {
"X-Bili-Accesskeyid": access_key_id,
"X-Bili-Signature-Version": "2.0",
"X-Bili-Signature-Method": "HMAC-SHA256",
"X-Bili-Timestamp": timestamp,
"X-Bili-Signature-Nonce": nonce,
"X-Bili-Content-Md5": content_md5,
"Authorization": signature,
"Access-Token": access_token,
"Content-Type": "application/json"
}
# 发送请求
response = requests.get(url, params=params, headers=headers)
# 解析响应
if response.status_code == 200:
result = response.json()
if result.get("code") == 0:
return result.get("data", {})
else:
print(f"接口调用失败:{result.get('message')}")
else:
print(f"HTTP请求失败:状态码{response.status_code}")
return {}
# 调用示例
if __name__ == "__main__":
ACCESS_KEY_ID = "你的AccessKeyId"
ACCESS_KEY_SECRET = "你的AccessKeySecret"
ACCESS_TOKEN = "你的Access-Token"
video_list = get_authorized_video_list(ACCESS_KEY_ID, ACCESS_KEY_SECRET, ACCESS_TOKEN, pn=1, ps=10)
print("授权用户视频列表:", video_list)4.2 Web端接口示例:查询公开视频详情
import requests
def get_public_video_detail(bvid: str) -> Dict[str, Any]:
url = "https://api.bilibili.com/x/web-interface/wbi/view"
params = {
"bvid": bvid
}
# 构造请求头(添加Cookie以访问需登录可见的视频)
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Cookie": "SESSDATA=你的SESSDATA值; bili_jct=你的bili_jct值" # 从浏览器开发者工具获取
}
response = requests.get(url, params=params, headers=headers)
if response.status_code == 200:
result = response.json()
if result.get("code") == 0:
return result.get("data", {})
else:
print(f"接口调用失败:{result.get('message')}")
else:
print(f"HTTP请求失败:状态码{response.status_code}")
return {}
# 调用示例(查询BV1MW421X7gM的视频详情)
if __name__ == "__main__":
video_detail = get_public_video_detail("BV1MW421X7gM")
print("视频标题:", video_detail.get("title"))
print("播放量:", video_detail.get("stat", {}).get("play"))
print("UP主:", video_detail.get("owner", {}).get("name"))五、常见问题与避坑指南
5.1 认证相关错误
错误码401/签名验证失败:检查AccessKeyId、AccessKeySecret是否正确;确认签名计算时参数排序、拼接格式正确;检查timestamp与当前时间是否一致(误差不超过5分钟)。
错误码403/权限不足:确认已申请
ARC_BASE权限;检查Access-Token是否有效(用户授权过期需重新获取)。
5.2 接口调用限制
官方接口:存在QPS限制(具体以开放平台文档为准),高频调用需做好限流处理,避免账号被封禁。
Web端接口:无明确QPS限制,但建议添加请求间隔(如time.sleep(1)),避免触发B站反爬机制;Cookie中的SESSDATA过期后需重新获取。
5.3 数据解析问题
时间戳转换:响应中的ctime、ptime为UTC时间戳,需转换为本地时间(Python可使用datetime模块:
datetime.fromtimestamp(时间戳))。分P视频信息:Web端接口的pages字段包含分P列表,需遍历获取各分P的cid、时长等信息。
5.4 合规性提醒
六、总结与扩展
批量数据获取:结合分页参数实现多页视频列表抓取,添加异常重试机制提升稳定性;
数据可视化:将获取的播放量、点赞数等数据通过Matplotlib、ECharts生成图表;
其他接口探索:B站开放平台还提供视频发布、评论管理等接口,可进一步扩展功能。
