B站视频数据抓取教程:用 API 按关键词批量获取 bvid、标题、UP主等字段
一、问题:想批量拿 B 站视频数据,官方没给你现成接口
做内容分析、UP 主研究、选题调研,或者搭一个自己的视频监测面板,很多人第一步就卡在「怎么把 B 站的搜索结果变成一张结构化的表」。你想要的其实很朴素:给一个关键词,返回一批视频,每条带上 bvid、标题、UP 主、时长、链接 这些字段,直接能落库分析。
但 B 站并没有对外提供一个稳定、好用的开放搜索接口。自己去啃网页又有一堆麻烦事:
- 搜索结果是动态渲染的,直接抓 HTML 拿不到干净数据;
- 每个视频的关键标识是
bvid(还有旧的aid),你得知道去哪儿解析; - 翻页、风控、字段清洗全要自己处理;
- 好不容易写好了,B 站前端一改版,脚本就废。
二、手动方式的痛点
不用代码的话,就是在网页上一个个搜、一条条抄:视频标题、UP 主、播放时长,再手动去地址栏里把 BV 号抠出来。抄十条还行,抄一百条、还要每周更新一次,直接劝退。
而且手动抄下来的数据往往不规整:时长有的写「12:34」有的写「1:02:11」,bvid 容易抄错,链接经常忘了带。做后续分析时,光清洗就得花掉大半时间。
我们真正想要的,是一个输入关键词、输出结构化字段的接口。
三、方案:用 bilibili-video-search 这个 Actor
Apify 上的 bilibili-video-search 正好干这件事。它的输入参数:
keyword:搜索关键词(必填);max_results:最多返回多少条;addonSentimentScored:可选,是否附加情感打分;addonSocialHandlesExtracted:可选,是否提取社交账号信息。
而它返回的输出字段是明确的,这点对我们太友好了。每条视频包含:
| 字段 | 含义 |
|---|---|
bvid | 视频的 BV 号(B 站主用标识) |
aid | 视频的 av 号(旧标识) |
url | 视频链接 |
title | 视频标题 |
description | 视频简介 |
author | UP 主名称 |
mid | UP 主的用户 ID |
duration | 视频时长 |
Actor 页面:https://apify.com/nexgendata/bilibili-video-search?fpr=2ayu9b
3.1 最小可运行示例
用 Apify 的 run-sync-get-dataset-items 端点,一次请求同步拿到结果:
import requests
APIFY_TOKEN = "<你的-apify-token>"
ACTOR_SLUG = "nexgendata~bilibili-video-search"
ENDPOINT = (
f"https://api.apify.com/v2/acts/{ACTOR_SLUG}"
f"/run-sync-get-dataset-items?token={APIFY_TOKEN}"
)
payload = {
"keyword": "Python 教程",
"max_results": 30,
"addonSentimentScored": False,
"addonSocialHandlesExtracted": False,
}
resp = requests.post(ENDPOINT, json=payload, timeout=180)
resp.raise_for_status()
videos = resp.json()
# B 站搜索偶尔会被风控,此时接口会返回一条 {"status": "no_results_or_blocked"} 的占位记录,
# 而不是视频数据。先做一层判断,避免把占位记录当成真实结果。
if videos and isinstance(videos[0], dict) and videos[0].get("status") == "no_results_or_blocked":
print("本次未返回视频(可能被风控,或该关键词暂无结果),稍后重试或更换关键词即可")
videos = []
print(f"关键词『{payload['keyword']}』共抓到 {len(videos)} 条视频")
3.2 用真实字段名读取每条视频
因为输出 schema 是确定的,我们可以放心地按字段名取值。下面把每条视频的核心字段打印出来:
for v in videos[:5]:
print("标题:", v.get("title"))
print("UP主:", v.get("author"), "| mid:", v.get("mid"))
print("BV号:", v.get("bvid"), "| aid:", v.get("aid"))
print("时长:", v.get("duration"))
print("链接:", v.get("url"))
print("简介:", v.get("description"))
print("-" * 40)
输出大概长这样(示意):
标题: 30分钟Python入门
UP主: 某某编程 | mid: 12345678
BV号: BV1xx411c7XX | aid: 987654321
时长: 30:12
链接: https://www.bilibili.com/video/BV1xx411c7XX
简介: 面向零基础的Python快速入门...
----------------------------------------
3.3 存成 CSV,直接可分析
既然字段明确,就可以固定表头写 CSV,Excel 或 pandas 打开即用:
import csv
fields = ["bvid", "aid", "title", "author", "mid", "duration", "url", "description"]
with open("bilibili_videos.csv", "w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=fields, extrasaction="ignore")
writer.writeheader()
for v in videos:
writer.writerow(v)
print("已保存到 bilibili_videos.csv")
extrasaction="ignore" 保证即使某条数据多出别的键也不会报错,utf-8-sig 让中文在 Excel 里不乱码。
3.4 用 pandas 做点简单统计
有了结构化数据,做分析就顺手了。比如统计不同 UP 主贡献了多少条视频:
import pandas as pd
df = pd.DataFrame(videos)
print("字段列:", list(df.columns))
# 按 UP 主统计视频数量
top_authors = df["author"].value_counts().head(10)
print(top_authors)
# 按 bvid 去重,避免重复视频
df = df.drop_duplicates(subset=["bvid"])
print("去重后视频数:", len(df))
bvid 是每个视频的唯一标识,用它来去重最稳妥。
四、定时与自动化:让关键词监测跑起来
如果你想持续追踪某些关键词下的新视频,可以把多个关键词封装成循环,再配上定时任务:
import time
def search_bili(keyword, n=30):
payload = {
"keyword": keyword,
"max_results": n,
"addonSentimentScored": False,
"addonSocialHandlesExtracted": False,
}
r = requests.post(ENDPOINT, json=payload, timeout=180)
r.raise_for_status()
return r.json()
keywords = ["Python 教程", "机器学习", "数据分析"]
seen_bvid = set() # 生产环境里换成数据库
for kw in keywords:
for v in search_bili(kw):
bvid = v.get("bvid")
if bvid and bvid not in seen_bvid:
seen_bvid.add(bvid)
print(f"[新视频] {kw} | {v.get('title')} | {v.get('url')}")
time.sleep(2)
再套上 Apify 的 Schedule 或本地 crontab(比如每天跑一次),就能实现「只提醒我关键词下的新视频」。crontab 示例:
0 9 * * * /usr/bin/python3 /home/you/jobs/watch_bili.py >> /home/you/logs/bili.log 2>&1
五、小结
B 站视频数据抓取的核心难点,是把动态网页变成可分析的结构化字段。bilibili-video-search 这个 Actor 直接给了你确定的输出:bvid、aid、url、title、description、author、mid、duration,输入只要一个 keyword 加 max_results。这样你写几十行 Python 就能搭起从「搜索」到「入库分析」的完整链路,不用再跟前端改版死磕。
更多面向中文与 APAC 场景的数据采集 Actor,可以到 https://thenextgennexus.com 看看。欢迎在评论区分享你用它做了什么有意思的分析。