哔哩哔哩 item_get_video - 获取视频详情接口对接全攻略:从入门到精通

哔哩哔哩(B 站)作为国内领先的视频社区,其item_get_video接口是获取单条视频精细化详情的核心工具,可返回视频播放地址、分集信息、互动数据、UP 主信息等关键内容,广泛应用于视频聚合平台、内容数据分析、二次创作素材调研、舆情监测等场景。

本攻略从接口认知、前置准备、实操对接、调试优化到合规上线,提供全流程结构化指导,兼顾入门易用性与生产级稳定性,助力开发者高效完成对接。

一、接口核心认知:功能与适配场景

1. 接口定位与核心价值

  • 核心功能:输入 B 站视频 AV 号 / BV 号 / 视频 ID,即可获取该视频的基础信息、播放数据、互动数据、UP 主信息、分集列表等全量详情,部分接口还支持返回视频字幕、分 P 时长、版权信息等进阶字段。
  • B 站平台特性
    • 数据覆盖:支持番剧、国创、UP 主自制视频、直播回放等全品类视频,新视频收录延迟 5-10 分钟;
    • 专属字段:包含 B 站独有的弹幕数、投币数、收藏数、充电数 等互动指标,以及分区标签、创作激励状态等平台特色字段;
    • 权限分层:基础字段(标题、播放量)支持普通权限,进阶字段(播放链接、字幕)需企业级或专项权限;
    • 多格式兼容:支持 AV 号(旧格式)、BV 号(新格式)、video_id(接口专用 ID)三种标识查询。
  • 典型应用场景
    1. 视频聚合工具:接入 B 站视频详情,为用户提供一站式视频检索与播放入口;
    2. 内容数据分析:采集视频互动数据,分析不同分区内容的用户偏好、爆款视频特征;
    3. 二次创作调研:获取视频标签、简介等信息,辅助创作者定位选题方向;
    4. 舆情监测:追踪品牌 / 事件相关视频的传播数据(播放量、评论数),掌握舆论走向;
    5. 番剧运营分析:获取番剧分集播放数据,评估剧集热度与用户追更意愿。

2. 核心参数与返回字段

(1)请求参数(必填 + 可选,按优先级排序)
参数名称 类型 是否必填 说明 应用示例
appkey string 接口调用密钥,由 B 站开放平台 / 合规服务商分配 bilibili_123abc
secret string 签名密钥,用于请求合法性校验(不可泄露) bilibili_def456
video_id string 视频标识,支持 AV 号(av123456)、BV 号(BV1xx411c7m9)、接口专用 video_id BV1xx411c7m9
need_page int 是否返回分 P 信息,默认 1(返回) 1(返回分 P)、0(仅返回主视频)
need_danmu int 是否返回弹幕相关数据,默认 0(不返回) 1(返回弹幕数 / 弹幕关键词)
need_up_info int 是否返回 UP 主详细信息,默认 1(返回) 0(仅返回 UP 主 ID / 昵称)
timestamp long 请求时间戳(毫秒级,有效期 5 分钟) 1735689600000
sign string 签名值(按 B 站规则生成,核心校验项) 32 位 MD5 大写串

注意事项

  1. 视频标识优先级:video_id 传入 BV 号时,接口会自动转换为内部 ID,无需手动解析;
  2. 权限关联:need_danmu=1 需额外申请弹幕数据权限,普通账号默认不开放。
(2)返回核心字段(按业务场景分类)
字段分类 核心字段 说明
视频基础信息 bvid 视频 BV 号(对外唯一标识)
aid 视频 AV 号(旧标识,部分场景兼容)
title 视频标题(含分区前缀 / 营销文案)
cover_url 视频封面图 URL(高清)
duration 视频总时长(秒,分 P 视频为所有分 P 总和)
pubdate 视频发布时间(时间戳 / 格式化时间)
cid 视频分 P 标识(单 P 视频 cid 唯一,多 P 视频每个分 P 对应一个 cid)
desc 视频简介(UP 主自定义文案)
tags 视频标签列表(如 "原神""教程""搞笑")
category 视频分区(如 "游戏 - 原神""知识 - 科普")
播放与互动数据 view 累计播放量
danmaku 累计弹幕数
reply 评论数
favorite 收藏数
coin 投币数
like 点赞数
share 转发数
charge 充电数(用户对 UP 主的打赏)
current_rank 全站实时排名(部分热门视频有值)
分 P 信息(need_page=1 时返回) pages 分 P 列表,包含分 P 标题、时长、cid
page_count 分 P 总数
UP 主信息 mid UP 主 ID
name UP 主昵称
face UP 主头像 URL
follower UP 主粉丝数
level UP 主等级(1-6 级)
official_verify 认证类型(个人 / 企业 / 官方)
其他字段 copyright 版权类型(1 = 原创,2 = 转载)
state 视频状态(0 = 正常,-1 = 审核中,-2 = 已下架)
play_url 视频播放链接(需权限,部分接口仅返回跳转链接)

3. 接口限制与注意事项

  • 调用频率限制

    账号类型 调用频率 适用场景
    个人开发者 5 次 / 分钟 个人素材调研、小型分析工具
    企业开发者 30 次 / 分钟 商业数据分析、内容聚合平台
  • 数据缓存规则:视频基础信息缓存 1 小时,互动数据(播放量 / 点赞数)缓存 5 分钟,热门视频缓存时效缩短至 1 分钟;

  • 内容限制:已下架 / 违规视频、隐私视频(仅粉丝可见)、未过审视频不会返回;番剧等版权内容仅返回基础信息,无播放链接;

  • 合规要求:禁止通过接口获取视频源文件进行盗播,播放链接需跳转至 B 站站内,二次创作需遵守 B 站版权规则。

二、对接前准备:权限与环境搭建

1. 获取接口权限(两种接入方式)

B 站item_get_video接口无公开免费接入渠道,需通过官方开放平台合规第三方服务商获取权限,具体对比如下:

接入方式 操作步骤 优缺点
B 站开放平台(官方) 1. 登录B站开发平台;2. 完成账号认证(个人实名认证 / 企业营业执照认证);3. 创建应用,选择 "内容数据 / 视频服务" 类目;4. 申请item_get_video接口权限,提交业务用途说明;5. 审核通过后,在应用详情页获取appkeysecret 优点:数据权威、字段完整、合规性强;缺点:审核严格(企业需提供业务证明)、周期长(3-7 个工作日)、部分字段(播放链接)需专项授权
第三方合规服务商 1. 选择口碑合规的服务商(如聚合数据、APISpace);2. 注册账号并完成实名认证;3. 购买 B 站视频接口套餐;4. 在服务商后台获取appkey和接口调用地址 优点:接入快(10 分钟完成)、无需复杂资质、调试工具完善;缺点:部分进阶字段(弹幕关键词)需付费升级、调用次数有配额限制

风险提示:严禁使用非法爬虫接口,违反 B 站用户协议及《网络安全法》,存在账号封禁、法律追责风险。

2. 技术环境准备

(1)支持语言与协议
  • 协议:HTTPS(强制,保障数据传输安全);
  • 开发语言:支持 Python、Java、PHP、Go 等所有主流语言,推荐Python(数据处理便捷,适配多场景解析需求)。
(2)必备工具与依赖
工具类型 推荐工具 用途
调试工具 Postman 快速验证接口可用性,排除代码逻辑干扰
在线 MD5 工具 校验签名生成正确性
B 站 BV 号 / AV 号转换器 验证视频标识有效性
开发依赖 requests(Python) 发送 HTTP 请求
hashlib(Python) 生成接口签名
pandas(Python) 批量整理视频数据
jsonpath-ng 快速解析嵌套 JSON 响应
辅助工具 Redis 缓存视频详情,减少重复请求
logging 记录接口调用日志,便于问题追溯

三、实操步骤:接口对接全流程(Python 示例)

步骤 1:理解 B 站接口签名规则

B 站官方接口签名采用MD5 加密 ,第三方服务商通常沿用类似规则,核心逻辑为参数排序 + 拼接密钥 + MD5 加密,具体步骤如下:

  1. 剔除参数中的sign字段(若存在);
  2. 将剩余参数按参数名 ASCII 升序排序;
  3. 拼接为key1=value1&key2=value2&...的字符串;
  4. 在字符串末尾拼接&secret=你的secret
  5. 对拼接后的字符串进行 MD5 加密,生成 32 位大写字符串即为sign
签名示例

假设参数:appkey=bilibili_123abcvideo_id=BV1xx411c7m9timestamp=1735689600000secret=bilibili_def456

  1. 排序后参数:appkeytimestampvideo_id
  2. 拼接字符串:appkey=bilibili_123abc×tamp=1735689600000&video_id=BV1xx411c7m9&secret=bilibili_def456
  3. MD5 加密后得到signA1B2C3D4E5F67890123456789ABCDEF0

步骤 2:完整代码实现(Python)

(1)依赖安装

bash

复制代码
pip install requests pandas jsonpath-ng
(2)核心代码(含签名生成、接口调用、数据解析)
python 复制代码
import requests
import hashlib
import time
import json
import pandas as pd
from urllib.parse import urlencode
from jsonpath_ng import parse
import logging
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
# 日志配置(记录接口调用与错误信息)
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s",
    handlers=[logging.FileHandler("bilibili_item_get_video.log"), logging.StreamHandler()]
)

# 接口配置(替换为自身的appkey、secret、接口地址)
CONFIG = {
    "appkey": "你的appkey",
    "secret": "你的secret",
    "api_url": "https://api.example.com/bilibili/item_get_video",  # 官方/服务商接口地址
    "save_path": "B站视频详情.xlsx"
}

def generate_sign(params: dict, secret: str) -> str:
    """生成B站接口签名(MD5 32位大写)"""
    # 移除sign字段(若存在)
    params.pop("sign", None)
    # 按参数名ASCII升序排序
    sorted_params = sorted(params.items(), key=lambda x: x[0])
    # 拼接参数字符串并追加secret
    param_str = urlencode(sorted_params, encoding="utf-8") + f"&secret={secret}"
    # MD5加密并转大写
    md5 = hashlib.md5()
    md5.update(param_str.encode("utf-8"))
    return md5.hexdigest().upper()

def parse_bilibili_data(raw_data: dict) -> dict:
    """解析B站视频原始数据,标准化输出格式"""
    # 提取UP主信息
    up_info = raw_data.get("owner", {}) or raw_data.get("up_info", {})
    # 提取分P信息
    page_info = raw_data.get("pages", [])
    page_count = len(page_info) if page_info else 1
    page_titles = [page.get("part", "") for page in page_info] if page_info else [raw_data.get("title", "")]

    # 格式化时间
    pubdate = raw_data.get("pubdate", 0)
    pubdate_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(pubdate)) if pubdate else ""

    return {
        "BV号": raw_data.get("bvid", ""),
        "AV号": raw_data.get("aid", ""),
        "视频标题": raw_data.get("title", ""),
        "封面链接": raw_data.get("pic", raw_data.get("cover_url", "")),
        "总时长(分:秒)": f"{raw_data.get('duration', 0)//60}:{raw_data.get('duration', 0)%60:02d}",
        "发布时间": pubdate_str,
        "视频分区": raw_data.get("tname", raw_data.get("category", "")),
        "视频标签": ",".join(raw_data.get("tags", [])),
        "视频简介": raw_data.get("desc", ""),
        "版权类型": "原创" if raw_data.get("copyright", 2) == 1 else "转载",
        "视频状态": "正常" if raw_data.get("state", 0) == 0 else "审核中" if raw_data.get("state") == -1 else "已下架",
        "播放量": raw_data.get("view", 0),
        "弹幕数": raw_data.get("danmaku", 0),
        "评论数": raw_data.get("reply", 0),
        "收藏数": raw_data.get("favorite", 0),
        "投币数": raw_data.get("coin", 0),
        "点赞数": raw_data.get("like", 0),
        "转发数": raw_data.get("share", 0),
        "充电数": raw_data.get("charge", 0),
        "分P总数": page_count,
        "分P标题": "|".join(page_titles),
        "UP主ID": up_info.get("mid", ""),
        "UP主昵称": up_info.get("name", up_info.get("uname", "")),
        "UP主头像": up_info.get("face", ""),
        "UP主粉丝数": up_info.get("follower", 0),
        "UP主等级": up_info.get("level", 0),
        "认证类型": up_info.get("official_verify", {}).get("type", -1),
        "播放链接": raw_data.get("play_url", "需跳转B站站内"),
        "请求时间": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    }

def bilibili_item_get_video(
    video_id: str,
    need_page: int = 1,
    need_up_info: int = 1,
    need_danmu: int = 0
) -> dict:
    """
    调用B站item_get_video接口,获取视频详情
    :param video_id: BV号/AV号/接口video_id
    :param need_page: 是否返回分P信息
    :param need_up_info: 是否返回UP主详情
    :param need_danmu: 是否返回弹幕数据
    :return: 标准化的视频详情
    """
    # 1. 构建基础参数
    params = {
        "appkey": CONFIG["appkey"],
        "video_id": video_id,
        "need_page": need_page,
        "need_up_info": need_up_info,
        "need_danmu": need_danmu,
        "timestamp": int(time.time() * 1000)
    }

    # 2. 生成签名
    params["sign"] = generate_sign(params, CONFIG["secret"])

    try:
        # 3. 发送POST请求
        response = requests.post(
            url=CONFIG["api_url"],
            data=json.dumps(params),
            headers={"Content-Type": "application/json"},
            timeout=15,
            verify=True
        )
        response.raise_for_status()  # 抛出HTTP异常
        result = response.json()

        # 4. 解析响应
        if result.get("code") == 0 or result.get("status") == "success":
            raw_video = result.get("data", result.get("result", {}))
            if not raw_video:
                logging.warning(f"无视频数据返回(视频ID:{video_id})")
                return {"success": False, "error_msg": "无视频数据"}
            
            standard_data = parse_bilibili_data(raw_video)
            return {
                "success": True,
                "data": standard_data,
                "error_msg": ""
            }
        else:
            error_msg = result.get("msg", result.get("message", "接口调用失败"))
            logging.error(f"接口返回错误(视频ID:{video_id}):{error_msg}(code={result.get('code')})")
            return {"success": False, "error_msg": error_msg}
    except requests.exceptions.RequestException as e:
        logging.error(f"网络请求异常(视频ID:{video_id}):{str(e)}")
        return {"success": False, "error_msg": f"网络异常:{str(e)}"}
    except Exception as e:
        logging.error(f"数据解析异常(视频ID:{video_id}):{str(e)}")
        return {"success": False, "error_msg": f"解析异常:{str(e)}"}

def batch_get_video_detail(video_ids: list, **kwargs) -> list:
    """批量获取多个视频的详情"""
    all_videos = []
    for idx, vid in enumerate(video_ids):
        logging.info(f"正在获取第{idx+1}个视频(ID:{vid})")
        result = bilibili_item_get_video(vid,** kwargs)
        if result["success"]:
            all_videos.append(result["data"])
            logging.info(f"视频{vid}获取成功")
        else:
            logging.error(f"视频{vid}获取失败:{result['error_msg']}")
        # 控制调用频率(个人用户间隔12秒,企业用户间隔2秒)
        time.sleep(12)
    return all_videos

def save_video_detail(videos: list, save_path: str = CONFIG["save_path"]):
    """将视频详情保存为Excel"""
    if not videos:
        logging.warning("无视频数据可保存")
        return
    
    df = pd.DataFrame(videos)
    # 增量保存,避免覆盖历史数据
    try:
        history_df = pd.read_excel(save_path, engine="openpyxl")
        df = pd.concat([history_df, df], ignore_index=True).drop_duplicates(subset=["BV号"])
    except FileNotFoundError:
        pass
    
    df.to_excel(save_path, index=False, engine="openpyxl")
    logging.info(f"视频详情已保存至{save_path}(共{len(df)}条数据)")
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
# 调用示例
if __name__ == "__main__":
    # 单视频获取示例
    single_video_result = bilibili_item_get_video(video_id="BV1xx411c7m9")
    if single_video_result["success"]:
        print("B站视频详情:")
        for k, v in single_video_result["data"].items():
            print(f"{k}:{v}")
    else:
        print(f"获取失败:{single_video_result['error_msg']}")

    # 批量获取示例
    # video_list = ["BV1xx411c7m9", "BV1yt411g7qK", "av123456"]
    # batch_result = batch_get_video_detail(video_list)
    # save_video_detail(batch_result)

四、调试与问题排查:快速解决对接异常

1. 优先用 Postman 调试(排除代码干扰)

  1. 构造请求 :新建 POST 请求,填写接口 URL,请求头设置Content-Type: application/json
  2. 填写参数 :在请求体中输入appkeyvideo_idtimestamp等必填项,按需补充need_page等可选参数;
  3. 生成签名 :用在线 MD5 工具手动计算sign,填入参数;
  4. 发送请求:查看响应结果,验证接口可用性。

2. 高频问题排查表

问题现象 常见原因 解决方案
签名错误(401) 1. 参数排序错误;2. secret不匹配;3. 时间戳过期;4. 中文未 URL 编码 1. 按 ASCII 升序排序参数;2. 核对secret与后台一致;3. 校准本地时间(误差≤5 分钟);4. 确保urlencode处理特殊字符
权限不足(403) 1. 未申请item_get_video接口权限;2. 无分 P / 弹幕数据权限;3. 调用频率超限 1. 在开放平台确认接口已开通;2. 申请对应进阶权限;3. 增加请求间隔,降低调用频率
参数错误(400) 1. video_id格式错误(非 BV/AV 号);2. need_page等参数非 0/1;3. 字段类型错误 1. 验证video_id有效性(B 站官网可查询);2. 确保参数为 0/1 整数;3. 检查参数类型(如timestamp为数字)
无数据返回 1. 视频 ID 无效 / 已下架;2. 视频为隐私 / 版权受限内容;3. 接口未收录该视频 1. 核对视频 ID,在 B 站官网确认视频状态;2. 排除番剧等版权内容;3. 更换服务商或申请官方专项权限
字段缺失(如无播放链接) 1. 无播放权限;2. 番剧等版权内容限制;3. 接口版本不支持 1. 申请 B 站站内播放跳转权限;2. 仅展示基础信息,引导用户跳转 B 站;3. 升级接口版本

五、进阶优化:生产级稳定性提升

1. 性能优化

  • 异步并发请求 :批量获取多视频时,使用aiohttp实现异步请求,控制并发数≤5(避免频率超限),效率比同步提升 4-6 倍;
  • 智能缓存策略 :用 Redis 缓存视频详情,缓存 key 为bilibili_视频BV号,基础信息缓存 1 小时,互动数据缓存 5 分钟,减少重复请求;
  • 数据复用 :通过item_get_video获取的cid(分 P 标识),可联动 B 站其他接口获取分 P 播放数据,避免重复调用。

2. 数据质量优化

  • 数据去重 :按BV号去重,避免同一视频多次入库;
  • 异常值过滤:过滤播放量为 0、状态为下架的无效数据;
  • 字段补全:对缺失的分区 / 标签字段,通过视频标题关键词自动补充(如标题含 "原神" 则补充分区 "游戏 - 原神")。

3. 合规与安全

  • 密钥管理 :生产环境将appkeysecret存储在环境变量 / 配置中心(如 Nacos),禁止硬编码,定期轮换密钥;
  • 数据合规:视频数据仅用于合规业务,播放链接需跳转 B 站站内,二次创作需获得 UP 主授权,禁止盗播 / 商用;
  • 日志审计:详细记录接口调用的参数、响应、错误信息,保留至少 7 天日志,便于合规审计与问题追溯。

六、扩展场景:接口联动与功能升级

  1. 联动item_search_video接口 :先通过关键词搜索获取视频 ID 列表,再批量调用item_get_video获取详情,实现 "搜索 - 详情" 全链路;
  2. 爆款视频分析模型 :结合播放量点赞率(点赞 / 播放)、投币率等指标,构建爆款评分公式,自动筛选优质内容;
  3. 实时监控告警 :用APScheduler定时调用接口,监控目标视频的播放量 / 评论数变化,触发舆情 / 爆款告警。
相关推荐
沛沛老爹2 小时前
Web开发者实战RAG评估:从指标到工程化验证体系
前端·人工智能·llm·agent·rag·评估
qq_200465052 小时前
日益衰落的五常“礼、义、仁、智、信”,蒸蒸日上的五德“升、悟、净、正、合”
人工智能·起名大师·改名大师·姓名学大师·姓名学专家
Kiyra2 小时前
阿里云 OSS + STS:安全的文件上传方案
网络·人工智能·安全·阿里云·系统架构·云计算·json
程途拾光1582 小时前
自监督学习在无标签数据中的潜力释放
人工智能·学习
墨染天姬2 小时前
【AI】5w/1h分析法
人工智能
Blossom.1182 小时前
多模态大模型LoRA微调实战:从零构建企业级图文检索系统
人工智能·python·深度学习·学习·react.js·django·transformer
檐下翻书1733 小时前
模型蒸馏与压缩技术的新进展
人工智能
小陈phd3 小时前
Dify从入门到精通(一)——Dify环境搭建
人工智能
zabr3 小时前
前端已死?我用 Trae + Gemini 零代码手搓 3D 塔罗牌,找到了新出路
前端·人工智能·aigc