「 技术、数据、接口、系统问题欢迎留言私信获取系统演示和API调用 」
B 站item_search_video是目前开发者获取平台公开视频数据最稳定、合规的核心接口,支持关键词检索、分区筛选、时间范围、排序规则等精细化查询,返回视频基础信息、互动数据、UP 主信息等完整字段,广泛用于内容聚合、选题分析、行业数据监测、舆情监控等场景。
相比爬虫抓取,官方 / 合规服务商提供的接口无风控、无封禁、数据实时、支持高并发,是企业级应用的唯一合规选择。本文不讲空话,全程基于真实生产环境开发经验,补充签名机制、异常处理、生产优化、日志规范等专业内容,代码可直接上生产环境使用。
一、接口核心能力与应用场景
1. 接口定位
item_search_video是 B 站批量视频列表检索标准接口,支持多关键词组合检索,可按分区、发布时间、播放量、原创 / 转载、UP 主类型筛选,数据实时同步,新视频收录延迟仅 5-10 分钟,覆盖全品类公开视频数据。
2. 核心特性(生产环境必备)
- 多关键词逻辑:空格 = AND(同时包含),
|=OR(包含任一) - 排序支持:相关度、播放量、发布时间、点赞、弹幕、收藏
- 数据完整性:直接返回播放 / 点赞 / 弹幕 / 收藏,无需二次请求
- 合规性:仅返回公开数据,不涉及隐私、版权视频源文件
- 稳定性:企业级支持 30 次 / 分钟,个人 5 次 / 分钟,带缓存机制
3. 典型落地场景
- 垂直内容平台:聚合游戏、知识、美食等专区视频
- UP 主选题工具:分析同类视频热度、标签、互动数据
- 行业数据分析:统计领域视频趋势、用户偏好
- 舆情监控:实时监控品牌 / 事件相关视频数据变化
二、前置准备:权限申请 + 开发环境
1. 接口权限获取(唯一合规路径)
B 站不开放免费公共接口,只能通过两种方式接入:
- B 站开放平台(官方):企业认证、申请接口权限、审核 3-7 天,数据最全、合规性最高
- 合规第三方服务商:10 分钟开通、即用即买、调试友好,适合快速上线
严禁使用爬虫,违反《网络安全法》与 B 站用户协议,会导致法律风险与账号封禁。
2. 开发环境配置
- 协议:HTTPS 强制
- 语言:Python(推荐,数据处理最强)
- 核心依赖:
requestshashlibpandaslogging - 生产工具:Redis(缓存)、Postman(接口调试)
三、核心规则:B 站接口签名机制(必懂)
所有请求必须带签名sign,否则直接返回 401,标准签名流程:
- 排除
sign字段 - 所有参数按ASCII 升序排序
- 拼接成
key=value&key=value格式 - 末尾拼接
&secret=xxx - MD5 加密 → 32 位大写字符串
签名是接口对接 90% 报错的根源,必须严格遵守。
四、生产级 Python 代码实现(可直接上线)
1. 安装依赖
pip install requests pandas openpyxl
# API测试、系统演示控制台:http://console.open.onebound.cn/console/?i=Rookie
-
完整代码(含签名、日志、标准化、批量抓取、去重保存)
import requests
import hashlib
import time
import json
import logging
import pandas as pd
from urllib.parse import urlencode===================== 生产环境配置(建议放入环境变量,不要硬编码)=====================
CONFIG = {
"appkey": "你自己的appkey",
"secret": "你自己的secret",
"api_url": "https://api.open.onebound.cn/bilibili/item_search_video",
"save_file": "bilibili_video_result.xlsx",
"timeout": 15,
"request_interval": 12, # 个人账号12s,企业账号2s
}===================== 日志配置(生产必备)=====================
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[
logging.FileHandler("bilibili_api.log", encoding="utf-8"),
logging.StreamHandler()
]
)===================== 1. 签名生成函数(标准实现)=====================
def make_sign(params: dict, secret: str) -> str:
params_copy = {k: v for k, v in params.items() if v is not None and k != "sign"}
sorted_items = sorted(params_copy.items(), key=lambda x: x[0])
param_str = urlencode(sorted_items, encoding="utf-8")
final_str = param_str + f"&secret={secret}"
md5 = hashlib.md5()
md5.update(final_str.encode("utf-8"))
return md5.hexdigest().upper()===================== 2. 数据标准化(统一格式,方便入库)=====================
def format_video_data(item: dict, keyword: str) -> dict:
pub_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(item.get("pubdate", 0)))
duration = item.get("duration", 0)
duration_str = f"{duration//60}:{duration%60:02d}"return { "关键词": keyword, "BV号": item.get("bvid", ""), "标题": item.get("title", ""), "封面": item.get("cover_url", ""), "时长": duration_str, "发布时间": pub_time, "分区": item.get("category", ""), "标签": ",".join(item.get("tags", [])), "版权": "原创" if item.get("copyright") == 1 else "转载", "近30天播放": item.get("view", 0), "点赞": item.get("like", 0), "弹幕": item.get("danmaku", 0), "收藏": item.get("favorite", 0), "投币": item.get("coin", 0), "UP主ID": item.get("up_id", ""), "UP主名称": item.get("up_name", ""), "UP主类型": item.get("up_type", ""), }===================== 3. 单页接口请求 =====================
def video_search(keyword, **kwargs):
params = {
"appkey": CONFIG["appkey"],
"keyword": keyword,
"time_range": kwargs.get("time_range", "all"),
"sort_type": kwargs.get("sort_type", "relevance"),
"page_no": kwargs.get("page_no", 1),
"page_size": kwargs.get("page_size", 20),
"timestamp": int(time.time() * 1000),
}if kwargs.get("category"): params["category"] = kwargs["category"] if kwargs.get("up_type"): params["up_type"] = kwargs["up_type"] if kwargs.get("copyright"): params["copyright"] = kwargs["copyright"] if kwargs.get("time_range") == "custom": params["start_date"] = kwargs.get("start_date") params["end_date"] = kwargs.get("end_date") # 生成签名 params["sign"] = make_sign(params, CONFIG["secret"]) try: resp = requests.post( CONFIG["api_url"], data=json.dumps(params), headers={"Content-Type": "application/json"}, timeout=CONFIG["timeout"] ) resp.raise_for_status() result = resp.json() if result.get("code") != 0: logging.error(f"接口失败:{result.get('msg')}") return [] items = result.get("data", {}).get("item_list", []) return [format_video_data(i, keyword) for i in items] except Exception as e: logging.error(f"请求异常:{str(e)}") return []===================== 4. 批量多页抓取(带频率控制)=====================
def batch_search(keyword, max_page=5, **kwargs):
all_data = []
for page in range(1, max_page + 1):
logging.info(f"正在抓取第{page}页:{keyword}")
data = video_search(keyword, page_no=page, **kwargs)
if not data:
break
all_data.extend(data)
time.sleep(CONFIG["request_interval"])
return all_data===================== 5. 保存Excel(自动去重、增量保存)=====================
def save_to_excel(data):
if not data:
logging.warning("无数据可保存")
return
df_new = pd.DataFrame(data)
try:
df_old = pd.read_excel(CONFIG["save_file"])
df = pd.concat([df_old, df_new], ignore_index=True)
except:
df = df_new
df = df.drop_duplicates(subset=["BV号"])
df.to_excel(CONFIG["save_file"], index=False)
logging.info(f"保存成功,共{len(df)}条数据")===================== 测试调用 =====================
if name == "main":
# 搜索关键词:Python教程,知识分区,30天内,按播放量排序
video_list = batch_search(
keyword="Python教程 零基础",
category="knowledge",
time_range="30days",
sort_type="play",
max_page=3
)
save_to_excel(video_list)
五、高频错误排查表(开发必备)
表格
| 错误码 | 问题原因 | 解决方案 |
|---|---|---|
| 401 | 签名错误 /secret 错误 | 检查参数排序、编码、密钥 |
| 403 | 无权限 / 频率超限 | 申请接口权限、延长请求间隔 |
| 400 | 参数非法 | 检查分区名、日期格式 |
| 无数据 | 筛选过严 / 关键词过偏 | 放宽条件、简化关键词 |
| 时间戳过期 | 本地时间不准 | 同步网络时间 |
六、生产环境优化方案(企业级标准)
1. 接口性能优化
- Redis 缓存:相同关键词缓存 30 分钟,大幅减少请求量
- 异步请求 :使用
aiohttp并发抓取,效率提升 5 倍 - 智能停止:无数据自动停止翻页
2. 数据质量优化
- 按
BV号全局去重 - 过滤下架 / 0 播放无效视频
- 自动清洗标签、标题冗余字符
3. 合规安全规范
- appkey/secret 不硬编码,使用环境变量
- 每 3 个月轮换一次密钥
- 数据仅自用,不倒卖、不侵权
- 必须标注 "数据来源:哔哩哔哩"
4. 扩展功能(行业常用)
- 联动
item_get_video获取视频详情、字幕、分 P - 构建爆款评分模型:播放完成率、点赞率、弹幕密度
- 定时监控:APScheduler 定时抓取 + 异常告警
七、总结
item_search_video是 B 站生态最实用的批量视频数据接口,合规、稳定、功能完整,是内容平台、数据分析、舆情监控的底层支撑。
本文提供的代码完全生产可用,包含签名、日志、异常捕获、标准化、批量抓取、去重保存,新手可直接运行,企业可直接集成上线,彻底解决接口对接难、调试复杂、上线不稳定的问题。