文章目录
前言
在此之前,爬取了大仙投稿的全部视频的详细信息。【B站爬虫】爬取B站UP主指法芬芳张大仙投稿视频。提取出2020年度的视频数据,通过统计可以发现下图所示视频的弹幕数最多,本文以此视频为例对B站弹幕进行爬取,最后将爬取而得的弹幕信息可视化。
一、爬取视频弹幕相关信息
1.B站弹幕接口
通过百度和自己利用抓包工具研究发现,B站弹幕的接口:
- https://comment.bilibili.com/
cid
.xml- https://api.bilibili.com/x/v1/dm/list.so?oid=
cid
只需要获得视频的cid
即可得到视频的弹幕信息。
2.获取视频的cid
由于之前爬取得到的数据中没有视频的cid
号,因此需要先获取视频的cid
号才能获取弹幕数据。同样经过搜索研究,发现B站获取cid
号的接口:
https://api.bilibili.com/x/player/pagelist?bvid=
bvid
&jsonp=jsonp
通过视频的bvid
号即可得到视频的cid
号。在接口链接中输入上述视频的bvid
号:BV1S64y1M7Ro,进入页面查看结果:https://api.bilibili.com/x/player/pagelist?bvid=BV1S64y1M7Ro&jsonp=jsonp
利用JSON校验格式化工具查看结果:
由视频的bvid号获取视频的cid代码如下:
import requests
import json
# 请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.67',
}
# 获取视频的cid
def get_cid(bvid):
# API地址
API = 'https://api.bilibili.com/x/player/pagelist'
# 参数
params = {
'bvid': bvid,
'jsonp': 'jsonp',
}
# 发起请求
response = requests.get(url=API, headers=headers, params=params)
# 网页源代码
html = response.text
# html文档转换为字典
dict = json.loads(html)
result = dict["data"][0]["cid"]
return result
3.获取视频弹幕信息
以B站弹幕接口2为例对视频的弹幕信息进行爬取,在接口网址中输入上面得到的cid
号:172761939,进入页面查看结果:https://api.bilibili.com/x/v1/dm/list.so?oid=172761939
通过百度发现,每一个d标签代表一条弹幕,其属性p为该弹幕的相关信息,各字段以逗号分隔,各字段按顺序的含义如下:
- 弹幕在本视频的第几秒发送
- 弹幕类型
type | meaning |
---|---|
1~3 | 滚动弹幕 |
4 | 底端弹幕 |
6 | 顶端弹幕 |
7 | 逆向弹幕 |
8 | 高级弹幕 |
- 字号
- 弹幕颜色【十进制】
- 弹幕发送时间【时间戳】
- 弹幕池
type | meaning |
---|---|
0 | 普通池 |
1 | 字幕池 |
2 | 特殊池 |
- 发送者ID
- 弹幕在数据库中的行号
由视频的cid号获取视频弹幕信息,利用正则表达式进行数据解析,同时将结果存储为.xls文件代码如下:
import requests
import chardet
import re
import xlwt
# 请求头
headers = {
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.67",
}
def write_to_excel(words, filename, sheet_name='sheet1'):
try:
# 1、创建工作薄
work_book = xlwt.Workbook(encoding='utf-8')
# 2、创建sheet表单
sheet = work_book.add_sheet(sheet_name)
# 3、写表头
head = []
for k in words[0].keys():
head.append(k)
for i in range(len(head)):
sheet.write(0, i, head[i])
# 4、添加内容
# 行号
i = 1
for item in words:
for j in range(len(head)):
sheet.write(i, j, item[head[j]])
# 写完一行,将行号+1
i += 1
# 保存
work_book.save(filename)
print('写入excel成功!')
except Exception as e:
print('写入excel失败!', e)
# 爬取B站视频弹幕
def get_barrage(cid):
# API地址
API = 'https://api.bilibili.com/x/v1/dm/list.so'
# 参数
params = {
'oid': cid,
}
# 发起请求
response = requests.get(url=API, headers=headers, params=params)
# 网页源代码编码
response.encoding = chardet.detect(response.content)['encoding']
# 网页源代码
html = response.text
# 正则表达式预编译
pattern = re.compile(r'<d p="(.*?)">(.*?)</d>')
# 正则表达式数据解析
result = pattern.findall(html)
# 存放数据容器
words = []
# 计数器
count = 0
for item in result:
count += 1
info = item[0].split(',')
# 出现时间
appear_time = info[0]
# 类型
type = info[1]
# 字号
font_size = info[2]
# 字体颜色
font_color = info[3]
# 发送时间
send_time = info[4]
# 弹幕池
pool = info[5]
# 作者
author_id = info[6]
# 数据库记录
database_id = info[7]
# 弹幕内容
content = item[1]
words.append({
'atime': appear_time,
'type': type,
'font_size': font_size,
'font_color': font_color,
'send_time': send_time,
'pool': pool,
'author_id': author_id,
'database_id': database_id,
'content': content,
}