>

B站视频数据抓取教程:用 API 按关键词批量获取 bvid、标题、UP主

Reading Time: 2 minutes

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视频简介
authorUP 主名称
midUP 主的用户 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 直接给了你确定的输出:bvidaidurltitledescriptionauthormidduration,输入只要一个 keywordmax_results。这样你写几十行 Python 就能搭起从「搜索」到「入库分析」的完整链路,不用再跟前端改版死磕。

更多面向中文与 APAC 场景的数据采集 Actor,可以到 https://thenextgennexus.com 看看。欢迎在评论区分享你用它做了什么有意思的分析。