news 2026/1/15 10:18:22

哔哩哔哩 item_search_video - 根据关键词获取视频列表接口对接全攻略:从入门到精通

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
哔哩哔哩 item_search_video - 根据关键词获取视频列表接口对接全攻略:从入门到精通

哔哩哔哩(B 站)的item_search_video接口是通过关键词批量检索平台视频列表的核心工具,支持按分区、发布时间、播放量、UP 主类型等多维度筛选,返回视频基础信息、互动数据、UP 主信息等关键内容。该接口广泛适用于内容聚合平台搭建、视频选题调研、行业数据分析、舆情监测等场景。

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

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

1. 接口定位与核心价值

  • 核心功能:输入搜索关键词(支持多关键词组合),筛选 B 站全品类视频(番剧、UP 主自制、直播回放等),支持分区过滤、时间范围筛选、排序规则自定义,返回分页视频列表;可联动item_get_video接口获取单视频精细化详情。
  • B 站平台特性
    • 数据覆盖:收录 B 站 90% 以上公开视频,涵盖游戏、知识、生活、娱乐等 30 + 分区,新视频收录延迟 5-10 分钟;
    • 专属筛选维度:支持按分区(如游戏 - 原神)、UP 主认证类型(个人 / 企业 / 官方)、视频类型(原创 / 转载)筛选,适配精细化检索需求;
    • 互动数据前置:搜索结果直接返回播放量、点赞数、弹幕数等核心互动指标,无需二次调用;
    • 多关键词逻辑:支持空格分隔(AND 逻辑,同时含多个关键词)、竖线|分隔(OR 逻辑,含任一关键词)。
  • 典型应用场景
    1. 内容聚合工具:搭建垂直领域视频平台(如 “Python 教程”“美食探店” 专区),按关键词聚合 B 站相关视频;
    2. 选题调研:UP 主通过关键词检索,分析同类视频的热度、标签、互动数据,辅助确定创作方向;
    3. 行业数据分析:按行业关键词(如 “新能源汽车评测”)采集视频数据,统计分区热度、用户偏好;
    4. 舆情监测:追踪品牌 / 事件关键词相关视频,实时监控播放量、评论数变化,掌握舆论走向。

2. 核心参数与返回字段

(1)请求参数(必填 + 可选,按优先级排序)
参数名称类型是否必填说明应用示例
appkeystring接口调用密钥,由 B 站开放平台 / 合规服务商分配bilibili_abc123
secretstring签名密钥,用于请求合法性校验(不可泄露)bilibili_def456
keywordstring搜索关键词,支持多关键词组合(AND 用空格,OR 用 ``)Python教程 零基础、` 旅行 vlog美食探店 `
categorystring视频分区筛选,值为分区英文名(需参考 B 站分区字典)game(游戏)、knowledge(知识)、life(生活)
time_rangestring发布时间范围,默认all(全部)1day(1 天内)、7days(7 天内)、30days(30 天内)、custom(自定义,需配合 start/end_date)
start_datestring自定义开始日期(time_range=custom 时必填),格式YYYY-MM-DD2025-01-01
end_datestring自定义结束日期(time_range=custom 时必填),格式YYYY-MM-DD2025-12-31
sort_typestring排序方式,默认relevance(相关度优先)play(播放量倒序)、pubtime(发布时间倒序)、like(点赞数倒序)、danmaku(弹幕数倒序)
up_typestringUP 主认证类型,默认all(全部)personal(个人认证)、enterprise(企业认证)、official(官方认证)
copyrightint版权类型,默认0(全部)1(原创)、2(转载)
page_noint页码,默认1,最大支持1001510
page_sizeint每页视频数,默认20,最大支持50203050
timestamplong请求时间戳(毫秒级,有效期 5 分钟,避免重复请求)1735689600000
signstring签名值(按 B 站规则生成,核心校验项)32 位 MD5 大写串

注意事项

  1. 分区参数category需与 B 站官方分区英文名一致,可通过服务商文档获取分区字典;
  2. 时间范围优先级:custom模式下,start_dateend_date必须同时传入,且时间跨度不超过 1 年;
  3. 排序方式play对应的是近 30 天播放量,非累计播放量,适配爆款视频筛选。
(2)返回核心字段(按业务场景分类)
字段分类核心字段说明
视频基础信息bvid视频 BV 号(对外唯一标识)
title视频标题(含分区前缀、营销文案)
cover_url视频封面图 URL(高清)
duration视频时长(秒)
pubdate发布时间(时间戳 / 格式化字符串)
category视频分区(如 “游戏 - 原神”)
tags视频标签列表(如 “Python”“教程”“零基础”)
copyright版权类型(1 = 原创,2 = 转载)
state视频状态(0 = 正常,-1 = 审核中,-2 = 已下架)
互动数据view近 30 天播放量
like点赞数
danmaku弹幕数
favorite收藏数
coin投币数
share转发数
UP 主信息up_idUP 主 ID
up_nameUP 主昵称
up_avatarUP 主头像 URL
up_typeUP 主认证类型
up_fansUP 主粉丝数(部分接口需企业权限)
分页信息total关键词匹配视频总数
page_no当前页码
page_total总页码

3. 接口限制与注意事项

  • 调用频率限制
    账号类型调用频率适用场景
    个人开发者5 次 / 分钟个人选题调研、小型数据分析
    企业开发者30 次 / 分钟商业内容聚合、舆情监测系统
  • 数据缓存规则:搜索结果缓存 30 分钟,热门关键词(如 “原神”“演唱会”)缓存缩短至 10 分钟;企业用户可申请refresh=1强制刷新(需额外权限);
  • 内容限制:已下架 / 违规视频、隐私视频(仅粉丝可见)、未过审视频不会返回;番剧等版权内容仅返回基础信息,无播放链接;
  • 合规要求:禁止通过接口批量抓取视频源文件,搜索结果需标注 “数据来源:哔哩哔哩”,二次传播需遵守 B 站版权规则。

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

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

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

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

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

2. 技术环境准备

(1)支持语言与协议
  • 协议:HTTPS(强制,保障数据传输安全);
  • 开发语言:支持 Python、Java、PHP、Go 等所有主流语言,推荐Python(数据处理便捷,适配批量检索场景)。
(2)必备工具与依赖
工具类型推荐工具用途
调试工具Postman快速验证接口可用性,排除代码逻辑干扰
在线 MD5 工具校验签名生成正确性
B 站分区字典查询工具获取category参数的正确取值
开发依赖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_abc123keyword=Python教程sort_type=playtimestamp=1735689600000secret=bilibili_def456

  1. 排序后参数:appkeykeywordsort_typetimestamp
  2. 拼接字符串:appkey=bilibili_abc123&keyword=Python%E6%95%99%E7%A8%8B&sort_type=play×tamp=1735689600000&secret=bilibili_def456
  3. MD5 加密后得到sign3A9F7C2D1E0B86453210FEDCBA789654

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

(1)依赖安装

bash

pip install requests pandas jsonpath-ng
(2)核心代码(含签名生成、接口调用、数据保存)
import requests import hashlib import time import json import pandas as pd from urllib.parse import urlencode 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_search_video.log"), logging.StreamHandler()] ) # 接口配置(替换为自身的appkey、secret、接口地址) CONFIG = { "appkey": "你的appkey", "secret": "你的secret", "api_url": "https://api.example.com/bilibili/item_search_video", # 官方/服务商接口地址 "save_path": "B站视频搜索列表.xlsx" } def generate_sign(params: dict, secret: str) -> str: """生成B站接口签名(MD5 32位大写)""" # 1. 移除sign字段 params.pop("sign", None) # 2. 按参数名ASCII升序排序 sorted_params = sorted(params.items(), key=lambda x: x[0]) # 3. 拼接参数字符串并追加secret param_str = urlencode(sorted_params, encoding="utf-8") + f"&secret={secret}" # 4. MD5加密 md5 = hashlib.md5() md5.update(param_str.encode("utf-8")) return md5.hexdigest().upper() def standardize_video_data(raw_video: dict) -> dict: """标准化视频数据,统一输出格式""" # 格式化发布时间 pubdate = raw_video.get("pubdate", 0) pubdate_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(pubdate)) if pubdate else "" # 格式化视频时长 duration = raw_video.get("duration", 0) duration_str = f"{duration//60}:{duration%60:02d}" return { "搜索关键词": raw_video.get("keyword", ""), "BV号": raw_video.get("bvid", ""), "视频标题": raw_video.get("title", ""), "封面链接": raw_video.get("cover_url", ""), "视频时长": duration_str, "发布时间": pubdate_str, "视频分区": raw_video.get("category", ""), "视频标签": ",".join(raw_video.get("tags", [])) if raw_video.get("tags") else "", "版权类型": "原创" if raw_video.get("copyright", 2) == 1 else "转载", "视频状态": "正常" if raw_video.get("state", 0) == 0 else "已下架/违规", "近30天播放量": raw_video.get("view", 0), "点赞数": raw_video.get("like", 0), "弹幕数": raw_video.get("danmaku", 0), "收藏数": raw_video.get("favorite", 0), "投币数": raw_video.get("coin", 0), "转发数": raw_video.get("share", 0), "UP主ID": raw_video.get("up_id", ""), "UP主昵称": raw_video.get("up_name", ""), "UP主认证类型": raw_video.get("up_type", ""), "UP主粉丝数": raw_video.get("up_fans", 0), "请求时间": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) } def bilibili_item_search_video( keyword: str, category: str = None, time_range: str = "all", start_date: str = None, end_date: str = None, sort_type: str = "relevance", up_type: str = "all", copyright: int = 0, page_no: int = 1, page_size: int = 20 ) -> dict: """ 调用B站item_search_video接口,获取关键词视频列表 :param keyword: 搜索关键词 :param category: 视频分区 :param time_range: 发布时间范围 :param start_date: 自定义开始日期 :param end_date: 自定义结束日期 :param sort_type: 排序方式 :param up_type: UP主认证类型 :param copyright: 版权类型 :param page_no: 页码 :param page_size: 每页条数 :return: 标准化的视频列表数据 """ # 1. 校验参数合法性 if time_range == "custom" and not (start_date and end_date): logging.error("time_range=custom时,start_date和end_date为必填参数") return {"success": False, "error_msg": "缺少自定义时间参数"} # 2. 构建基础参数 params = { "appkey": CONFIG["appkey"], "keyword": keyword, "time_range": time_range, "sort_type": sort_type, "up_type": up_type, "copyright": copyright, "page_no": page_no, "page_size": page_size, "timestamp": int(time.time() * 1000) } # 3. 补充可选参数 if category: params["category"] = category if time_range == "custom": params["start_date"] = start_date params["end_date"] = end_date # 4. 生成签名 params["sign"] = generate_sign(params, CONFIG["secret"]) try: # 5. 发送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() # 6. 解析响应结果 if result.get("code") == 0 or result.get("status") == "success": raw_data = result.get("data", {}) video_list = raw_data.get("item_list", []) total = raw_data.get("total", 0) page_total = raw_data.get("page_total", 1) # 标准化视频数据 standard_videos = [] for video in video_list: video["keyword"] = keyword # 补充关键词字段 standard_videos.append(standardize_video_data(video)) return { "success": True, "data": standard_videos, "total": total, "page_no": page_no, "page_total": page_total, "error_msg": "" } else: error_msg = result.get("msg", result.get("message", "接口调用失败")) logging.error(f"接口返回错误(关键词:{keyword}):{error_msg}(code={result.get('code')})") return {"success": False, "error_msg": error_msg} except requests.exceptions.RequestException as e: logging.error(f"网络请求异常(关键词:{keyword}):{str(e)}") return {"success": False, "error_msg": f"网络异常:{str(e)}"} except Exception as e: logging.error(f"数据解析异常(关键词:{keyword}):{str(e)}") return {"success": False, "error_msg": f"解析异常:{str(e)}"} def batch_get_video_list( keyword: str, max_page: int = 5, **kwargs ) -> list: """批量获取多页视频列表,控制调用频率""" all_videos = [] page_no = 1 while True: logging.info(f"正在获取关键词「{keyword}」第 {page_no} 页视频") result = bilibili_item_search_video(keyword=keyword, page_no=page_no, **kwargs) if not result["success"]: logging.error(f"第 {page_no} 页获取失败:{result['error_msg']}") break page_videos = result["data"] if not page_videos: logging.info(f"第 {page_no} 页无视频数据,批量获取结束") break all_videos.extend(page_videos) logging.info(f"第 {page_no} 页获取成功,新增 {len(page_videos)} 条数据(累计 {len(all_videos)} 条)") # 终止条件:达到最大页码或总页码 if page_no >= max_page or page_no >= result["page_total"]: break page_no += 1 # 控制频率(个人用户间隔12秒,企业用户间隔2秒) time.sleep(12) return all_videos def save_video_list(videos: list, save_path: str = CONFIG["save_path"]): """将视频列表保存为Excel文件,支持增量去重""" if not videos: logging.warning("无视频数据可保存") return df = pd.DataFrame(videos) # 按BV号去重 df = df.drop_duplicates(subset=["BV号"]) # 增量保存 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__": # 单页获取示例:搜索“Python教程 零基础”,按播放量排序,知识分区,近30天 single_page_result = bilibili_item_search_video( keyword="Python教程 零基础", category="knowledge", time_range="30days", sort_type="play", page_size=20 ) if single_page_result["success"]: print(f"获取到 {len(single_page_result['data'])} 条视频数据") for video in single_page_result["data"][:5]: # 打印前5条 print(f"标题:{video['视频标题']} | 播放量:{video['近30天播放量']} | UP主:{video['UP主昵称']}") else: print(f"单页获取失败:{single_page_result['error_msg']}") # 批量获取示例:获取前5页数据并保存 # batch_videos = batch_get_video_list( # keyword="Python教程 零基础", # category="knowledge", # time_range="30days", # sort_type="play", # max_page=5 # ) # save_video_list(batch_videos)

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

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

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

2. 高频问题排查表

问题现象常见原因解决方案
签名错误(401)1. 参数排序错误;2.secret不匹配;3. 时间戳过期;4. 中文未 URL 编码1. 按 ASCII 升序排序参数并打印验证;2. 核对secret与后台一致;3. 校准本地时间(误差≤5 分钟);4. 确保urlencode处理特殊字符
权限不足(403)1. 未申请item_search_video接口权限;2. 普通账号使用企业字段(如 UP 主粉丝数);3. 调用频率超限1. 在开放平台确认接口已开通;2. 移除企业专属参数或升级账号;3. 增加请求间隔,降低调用频率
参数错误(400)1.category取值错误(非官方分区名);2.time_range=custom未传日期;3.sort_type取值非法1. 查阅服务商文档获取正确分区字典;2. 补充start_dateend_date;3. 核对sort_type取值(参考参数表)
无视频数据返回1. 关键词过于精准 / 无匹配视频;2. 筛选条件过于严格;3. 视频未被接口收录1. 放宽关键词(如 “Python 零基础” 改为 “Python 教程”);2. 移除分区 / 时间等筛选条件;3. 在 B 站官网搜索关键词,确认是否有相关视频
字段缺失(如无 UP 主粉丝数)1. 账号无企业权限;2. 接口版本不支持;3. UP 主隐私设置隐藏粉丝数1. 升级为企业账号或申请专项权限;2. 联系服务商升级接口版本;3. 忽略该字段,仅保留基础信息

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

1. 性能优化

  • 异步并发请求:多关键词 / 多页码批量获取时,使用aiohttp实现异步请求,控制并发数≤5(避免频率超限),效率比同步提升 4-6 倍;
  • 智能缓存策略:用 Redis 缓存关键词+筛选条件组合的搜索结果,缓存 key=bilibili_search_关键词_时间范围_分区,有效期 30 分钟;对无结果的关键词,缓存空结果(有效期 10 分钟),避免无效请求;
  • 分页智能停止:获取第 1 页后,根据page_total计算总页码,仅请求有效页码,避免page_no超过总页码的无效请求。

2. 数据质量优化

  • 数据去重:按BV号去重,避免同一视频多次入库;
  • 异常值过滤:过滤播放量为 0、状态为下架的无效数据;
  • 关键词扩展:结合 jieba 分词对核心关键词进行扩展(如 “Python 教程” 扩展为 “Python 零基础教程、Python 进阶教程”),提升搜索覆盖率。

3. 合规与安全

  • 密钥管理:生产环境中,将appkeysecret存储在环境变量或配置中心(如 Nacos),禁止硬编码;定期轮换密钥(每 3 个月一次);
  • 数据合规:搜索结果仅用于合规业务,禁止商业化售卖;引用视频数据时标注来源,二次创作需获得 UP 主授权;
  • 日志审计:详细记录每次接口调用的参数、响应、错误信息,保留至少 7 天日志,便于合规审计与问题追溯。

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

  1. 联动item_get_video接口:通过item_search_video获取bvid列表后,批量调用item_get_video获取视频分 P、字幕、播放链接等精细化详情;
  2. 爆款视频分析模型:结合播放量点赞率(点赞 / 播放)、弹幕率等指标,构建爆款评分公式,自动筛选优质视频;
  3. 实时关键词监测:使用APScheduler定时调用接口,监控目标关键词的视频新增量、播放量变化,触发舆情 / 爆款告警
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/3 12:20:33

【AI模型下载终极指南】:Open-AutoGLM提速90%的7种黑科技手段

第一章:Open-AutoGLM下载好慢在尝试本地部署 Open-AutoGLM 项目时,许多开发者反映其模型权重和依赖包的下载速度异常缓慢。该问题主要源于模型托管服务器位于境外,且未启用镜像加速机制。常见原因分析 原始 Hugging Face Hub 服务器对国内网络…

作者头像 李华
网站建设 2026/1/14 6:52:12

基于TensorFlow的姿态估计模型部署

基于TensorFlow的姿态估计模型部署 在智能摄像头越来越“懂人”的今天,你是否注意到:健身房的AI私教能实时纠正你的深蹲姿势,远程照护系统能在老人跌倒瞬间发出警报,甚至手机滤镜都能让虚拟猫耳随头部自然摆动?这些看似…

作者头像 李华
网站建设 2025/12/27 15:02:25

Open-AutoGLM部署实战经验分享,资深架构师亲授秘诀

第一章:Open-AutoGLM部署概述Open-AutoGLM 是一个开源的自动化通用语言模型部署框架,旨在简化大语言模型在生产环境中的集成与管理流程。该框架支持多种模型格式、推理引擎和部署平台,适用于从本地开发到云端集群的全场景部署需求。核心特性 …

作者头像 李华
网站建设 2026/1/15 3:10:01

为什么顶尖AI团队都在关注Open-AutoGLM?背后隐藏的5大战略价值

第一章:为什么顶尖AI团队都在关注Open-AutoGLM?在生成式AI快速演进的当下,自动化语言模型(AutoGLM)正成为提升研发效率的核心工具。而开源项目 Open-AutoGLM 凭借其模块化架构与高度可扩展性,吸引了包括谷歌…

作者头像 李华
网站建设 2025/12/27 15:01:10

java计算机毕业设计校园共享单车系统的设计与实现 高校共享单车站点调度与租赁管理平台 基于SpringBoot的校园智能单车租借系统

计算机毕业设计校园共享单车系统的设计与实现0v1439(配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。下课铃一响,同学们最焦虑的不是食堂排队,而是“找不到…

作者头像 李华
网站建设 2026/1/14 7:43:06

深度学习框架YOLOV8模型如何训练 监控视角交通目标车辆行人检测数据集 YOLO格式|高清路口实时监控|行人/车辆/多目标

监控视角交通目标车辆行人检测数据集 YOLO格式|高清路口实时监控|行人/车辆/多目标 ✅ 直接来自路口监控摄像头,非网络爬取、非二次加工 ✅ YOLO标准格式、 📊 数据集套餐价格表 等级数据量核心权益【1】5,000 张适合快速验证数…

作者头像 李华