一、EDG夺冠信息
11月6日,在英雄联盟总决赛中,EDG战队以 3:2 战胜韩国队,获得2021年 英雄联盟全球总决赛冠军 ,这个比赛在全网各大平台也是备受瞩目:
1、 微博 热搜 第一名 ,截止2021-11-10已有 亿级 观看量,微博粉丝数到达 638.4万
2、 哔哩哔哩 已有 几亿 人气,总弹幕有 22.3万 ,全站排行榜最高 第2名 ,B站粉丝已有 219.9万
3、 腾讯 、 爱奇艺 、 优酷 等视频平台 800万 人看过
4、 虎牙 等直播平台热度也是居高不下
5、 央视新闻 也发微博 庆祝EDG夺冠
既然比赛热度这么高,那么本次我们就以bilibili为基准,通过采集EDG夺冠比赛视频在哔哩哔哩的22.3万条弹幕数据,再通过Python来分析进而感受粉丝的热情
二、实战目标
1、利用爬虫技术抓取EDG战队在B站夺冠比赛视频的22.3万条弹幕数据
2、通过jieba、numpy等Python库对抓取来的弹幕数据进行分析并且可视化
三、bilibili接口分析
首先进入EDG夺冠比赛视频URL:
哔哩哔哩已为大家整理好了EDG比赛视频,从开幕式到夺冠时刻,共有7个视频
哔哩哔哩弹幕数据接口:
这个接口就是B站弹幕数据专用接口,我们可以直接拿来用,这个接口中的oid可以理解为每个视频中的唯一标识符,它由数字组成,每一个视频都有唯一的一个oid,那么我们只要找到oid就可以请求相应比赛视频弹幕的API接口,从而抓取弹幕数据
获取oid
打开开发者工具,切换到 Network 选项,然后找到以 pagelist 为开头的请求接口
接着找到Request URL这个请求接口,打开新窗口直接用这个API接口请求,如下图:
当我们直接请求这个API接口时可以看到 JSON 格式的数据,而在里面的cid就是我们需要的oid,如下所示:
1 {"code":0,"message":"0","ttl":1,"data":[{"cid":437586584,"page":1,"from":"vupload","part":"第一局 4K","duration":2952,"vid":"","weblink":"","dimension":{"width":1920,"height":1080,"rotate":0}},{"cid":437626309,"page":2,"from":"vupload","part":"第二局 4K","duration":3031,"vid":"","weblink":"","dimension":{"width":1920,"height":1080,"rotate":0}},{"cid":437659159,"page":3,"from":"vupload","part":"第三局 4K","duration":3406,"vid":"","weblink":"","dimension":{"width":1920,"height":1080,"rotate":0}},{"cid":437727348,"page":4,"from":"vupload","part":"第四局 4K","duration":3212,"vid":"","weblink":"","dimension":{"width":1920,"height":1080,"rotate":0}},{"cid":437729555,"page":5,"from":"vupload","part":"第五局 4K","duration":3478,"vid":"","weblink":"","dimension":{"width":1920,"height":1080,"rotate":0}},{"cid":437550300,"page":6,"from":"vupload","part":"开幕式","duration":984,"vid":"","weblink":"","dimension":{"width":1920,"height":1080,"rotate":0}},{"cid":437717574,"page":7,"from":"vupload","part":"夺冠时刻","duration":2017,"vid":"","weblink":"","dimension":{"width":1920,"height":1080,"rotate":0}}]
当然我们也可以点击 Preview 选项,点击data,打开数据,而里面的JSON数据是 折叠 的,包括cid在内,如下图所示:
可以看到,每个cid对应每一个比赛视频。我们也可以点击 Response 选项,里面的数据是真实的数据,意味着数据没有经过折叠,与直接请求Request URL返回的JSON数据是一样的
四、编码
定义一个获取cid的方法
1 import requests
2 import json
3
4
5 def get_cid():
6 url = 'https://api.bilibili.com/x/player/pagelist?bvid=BV1EP4y1j7kV&jsonp=jsonp'
7 try:
8 response = requests.get(url,timeout=None)
9 if response is not None:
10 return response.text
11 else:
12 return Nnone
13 except Exception as e:
14 print(e.args)
15
16
17 if __name__ == '__main__':
18 data = get_cid()
19 json_data = json.loads(data)
20 for cid_datas in json_data['data']:
21 cid = cid_datas.get('cid')
22 print(cid)
控制台输出如下:
拼接URL弹幕数据API接口
1 if __name__ == '__main__':
2 data = get_cid()
3 json_data = json.loads(data)
4 base_api = 'http://api.bilibili.com/x/v1/dm/list.so?oid='
5 for cid_datas in json_data['data']:
6 cid = cid_datas.get('cid')
7 detail_api = base_api + str(cid)
8 print(detail_api)
控制台输出如下:
一共有7个网址,对应7个EDG比赛视频的弹幕数据,我们点开第一个网址查看
抓取弹幕数据
从上一张图可以看到,每一条弹幕数据都在每一个标签中,面对这种格式我们思考一下用哪种解析工具比较合适?答案当然是正则表达式,接下来我们要获取7个比赛视频的22.3万条数据,代码如下:
1 base_api = 'http://api.bilibili.com/x/v1/dm/list.so?oid='
2 all_api = []
3 for cid_datas in json_data['data']:
4 cid = cid_datas.get('cid')
5 detail_api = base_api + str(cid)
6 all_api.append(detail_api)
7 for api in all_api:
8 edg_datas = get_api_data(detail_api)
9 edg_datas = re.findall('<d.*?>(.*?)</d>',edg_datas,re.S)
10 with open('EDG.txt','a',encoding='utf-8') as f:
11 for edg_data in edg_datas:
12 print(edg_data)
13 f.write(edg_data + '\n')
避免乱码,加上如下代码:
1 response.encoding = chardet.detect(response.content)['encoding']
控制台输出如下:
由于弹幕数据共有22.3万条,这里仅展示EDG.txt部分弹幕数据,如下图所示:
词云图制作
我们已经抓取到弹幕数据,接下来利用EDG背景图做一个词云图
代码如下:
1 import jieba
2 from wordcloud import WordCloud
3 import matplotlib.pyplot as plt
4 from PIL import Image
5 import numpy as np
6
7 def do_wordcloud():
8 text = open('EDG.txt','r',encoding='utf-8').read()
9 text = text.replace('\n','').replace('\u3000','')
10 text_cut = jieba.lcut(text)
11 text_cut = ' '.join(text_cut)
12
13 #过滤一些没有关系的词
14 stop_words = ['“',',',' ','我','的','是','了',':','?','!','啊','你','吗','。','我们']
15
16 background = Image.open("EDG.jpg")
17 graph = np.array(background)
18
19 word_cloud = WordCloud(font_path='simsun.ttc',
20 background_color='white',
21 mask=graph, # 指定词云的形状
22 stopwords=stop_words)
23
24 word_cloud.generate(text_cut)
25 plt.subplots(figsize=(12,8))
26 plt.imshow(word_cloud)
27 plt.axis('off')
28 plt.show()
29 word_cloud.to_file('edg.png')
控制台输出如下:
把 迪迦奥特曼 背景图片也制作一波吧,哈哈哈!
制作成 迪迦奥特曼 词云图形状,如下所示:
当然你也可以使用 pyecharts/echarts 制作也行,还可以制作成你喜欢的图片形状。如果你接触过 情感分析 的话,也可以用这些弹幕数据分析一波
五、总结
PIL库
jieba库
numpy库
requests库
wordcloud库
matplotlib库
json,re,chardet库
六、完整项目及源码下载
完整项目(包括源码)获取方式: 文末下载