把 B 站弹幕和评论抓下来之后,我发现「热梗」根本不在视频里

举报
yd_232652410 发表于 2026/10/26 16:03:26 2026/10/26
【摘要】 用三个公开 API 抓取 B 站视频的元数据、弹幕和评论,实现内容分析工具。记录了 protobuf 解析、gzip 识别、Referer 校验、代理环境 SSL 等四个工程坑,以及「弹幕比评论更真实」的分析心得。

把 B 站弹幕和评论抓下来之后,我发现「热梗」根本不在视频里

最近在做一个内容分析的小工具:给定一个视频,把它的弹幕和评论全抓下来,看看观众到底在讨论什么。

做完之后有个意外发现——**一个视频真正有意思的信息,几乎全在弹幕和评论里,不在视频本身**。

这篇记录实现过程,以及几个踩过的坑。

## 一、先说结论

拿一个播放量 311 万的视频做测试,三组数据的对比:

| 数据源 | 数据量 | 能拿到什么 |
|---|---|---|
| 视频画面 | 1 个文件 | 创作者想表达的内容 |
| 视频标题+简介 | 几百字 | 官方定位 |
| **弹幕** | **1030 条** | **观众的第一反应、集体玩梗** |
| **评论** | **44036 条** | **深度讨论、争议点、真实评价** |

弹幕和评论加起来是视频本身的几百倍信息量。

## 二、三个接口

B 站的核心数据都能通过公开 API 拿到,不需要登录(部分接口要 cookie)。

### 接口 1:视频基础信息

```python
import urllib.request, json

def get_video_info(bvid):
url = f'https://api.bilibili.com/x/web-interface/view?bvid={bvid}'
req = urllib.request.Request(url, headers={
'User-Agent': 'Mozilla/5.0 ...',
'Referer': 'https://www.bilibili.com/'
})
with urllib.request.urlopen(req, timeout=20) as r:
data = json.loads(r.read())
d = data['data']
return {
'title': d['title'],
'aid': d['aid'],
'cid': d['cid'],
'view': d['stat']['view'],
'danmaku': d['stat']['danmaku'],
'reply': d['stat']['reply'],
}
```

关键字段:`aid`(评论用)和 `cid`(弹幕用)。

### 接口 2:弹幕

这里踩了个坑。老接口 `x/v1/dm/list.so` 返回的是 **gzip 压缩的 protobuf**,直接 `decode('utf-8')` 会得到一堆乱码:

```python
# ❌ 这样拿到的是乱码
raw = urlopen('https://api.bilibili.com/x/v1/dm/list.so?oid=xxx').read()
txt = raw.decode('utf-8', 'ignore') # 得到 Yo]I&W40Xr: ...
```

正确的做法是用分段接口 `x/v2/dm/web/seg.so`,虽然也是 protobuf,但内容没压缩:

```python
import re

def get_danmaku(cid, aid, seg=1):
url = (f'https://api.bilibili.com/x/v2/dm/web/seg.so'
f'?type=1&oid={cid}&pid={aid}&segment_index={seg}')
req = urllib.request.Request(url, headers=HEADERS)
with urllib.request.urlopen(req, timeout=25) as r:
raw = r.read()

# protobuf 里中文以 UTF-8 明文存储,用正则粗提取
txt = raw.decode('utf-8', 'ignore')
chunks = re.findall(r'[\u4e00-\u9fff][\u4e00-\u9fff\w,。!?、~~]{2,20}', txt)
return chunks
```

每个 segment 对应视频的 6 分钟。一个 1 分钟的视频只需要 `segment_index=1`。

正则虽然"脏",但对中文弹幕的提取效果意外地好——实测一个视频能提到 208 条有效文本。

### 接口 3:评论

```python
def get_comments(aid, page=1, sort=2):
"""sort: 0=按时间, 1=按点赞, 2=按热度"""
url = (f'https://api.bilibili.com/x/v2/reply'
f'?type=1&oid={aid}&sort={sort}&ps=20&pn={page}')
req = urllib.request.Request(url, headers=HEADERS)
with urllib.request.urlopen(req, timeout=20) as r:
data = json.loads(r.read())
return data.get('data', {}).get('replies') or []
```

`sort=2`(按热度)是最有用的——高赞评论往往就是整个评论区的主旋律。

## 三、抓下来之后看到了什么

拿一个 AI 主题的视频测试,抓到的弹幕片段:

```
鲸小姐,这得花不少token,
这得吃不少大白饭,先生
到时候该不会外包给其他ai吧
细节没有画图做视频
先把规矩立住,路才能越走越宽
放心好了,隔壁Claude要担心自己的账号
从Claude那边过来的
鲸鲸加油
雷霆大思考
现在关注我就是老粉了
```

高赞评论:

```
[1863赞] 大肥鱼你简介怎么照抄隔壁的claude啊😡
[1197赞] 你是怎么在B站考了60分,还这么自信的啊
[142赞] 省流:偷懒不会回,从昨天发到现在几十条评论没有一个回复的
```

几个观察:

**1. 弹幕是「集体即兴」**
观众在同一条弹幕上叠加、变形、接梗。`这得花不少token` → `这得吃不少大白饭` 是同一个人改的,后面的人跟着刷。

**2. 评论是「分层的」**
- 前 3 条高赞:全是挑刺/玩梗
- 中间层:认真讨论
- 底层:作者回复区(如果有)

**3. 真正的「人设」在弹幕里**
创作者在视频里说「我是鲸鱼」,但弹幕反复叫「大肥鱼」「猫娘」——这种**错位**才是这个账号的传播核心。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。