VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > python入门教程 >
  • EDG夺冠!用Python分析22.3万条数据:粉丝都疯了!

一、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来分析进而感受粉丝的热情

 


 

二、实战目标 

2.1 网络爬虫

利用爬虫技术抓取EDG战队在B站夺冠比赛视频的22.3万条弹幕数据

 

2.2 数据可视化

通过jieba、numpy等Python库对抓取来的弹幕数据进行分析并且可视化

 

 

2.3 自然语言处理(情感分析)

利用pandas+自然语言处理(NLP)等对EDG夺冠比赛视频的弹幕数据进行情感分析,根据分析结果得出一些结论

 

 

 

 

 

 

 

 

 


 

三、bilibili接口分析 

首先进入EDG夺冠比赛视频URL:

https://www.bilibili.com/video/BV1EP4y1j7kV?p=1

 

哔哩哔哩已为大家整理好了EDG比赛视频,从开幕式到夺冠时刻,共有7个视频

 

哔哩哔哩弹幕数据接口:

http://api.bilibili.com/x/v1/dm/list.so?oid=XXX

这个接口就是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数据是一样的

 


 

 四、编码 

4.1 爬取数据

定义一个获取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比赛视频的弹幕数据,我们点开第一个网址查看

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

抓取弹幕数据

从上一张图可以看到,每一条弹幕数据都在每一个<d>标签中,面对这种格式我们思考一下用哪种解析工具比较合适?答案当然是正则表达式,接下来我们要获取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部分弹幕数据,如下图所示:

 

4.2 数据可视化(词云图)

词云图制作

我们已经抓取到弹幕数据,接下来利用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制作也行,还可以制作成你喜欢的图片形状。如果你接触过情感分析的话,也可以用这些弹幕数据分析一波

 


 

五、自然语言处理(NLP)

5.1 数据导入

1 data = pd.read_csv('EDG.csv')
2 data = data.head()
3 print(data)

 

控制台输出:

 

5.2 数据预处理

1 data = pd.read_csv('EDG.csv')
2 data = data[['id','content']]
3 data = data.head(10)
4 print(data)

 

控制台输出:

 

5.3 情感分析

先安装一下用于情感分析的Python库:

1 pip install snownlp -i https://pypi.doubanio.com/simple

 

效果如下:

 

情感分析

1 from snownlp import SnowNLP
2 data1['emotion'] = data1['content'].apply(lambda x:SnowNLP(x).sentiments)
3 data1 = data1.head()
4 print(data1)

 

控制台输出:

 

情感数据描述

1 data1 = data1.describe()

 

控制台输出:

数据说明emotion的平均值为0.63,中位数为0.67,25%分位数为0.49,可见不到25%的数据造成了整体均值的较大下移。另外上图的最下面可以看到,情感分析执行时间为48.8s,数据量还是挺大的。

 

5.4 情感分析直方图

复制代码
 1 plt.rcParams['font.sans-serif'] = ['SimHei']
 2 plt.rcParams['axes.unicode_minus'] = False
 3 
 4 bins = np.arange(0,1.1,0.1)    #设置区间
 5 plt.hist(data1['emotion'],bins,color='#4F94CD',alpha=0.9)
 6 plt.xlim(0,1)
 7 plt.xlabel('情感分析')
 8 plt.ylabel('数量')
 9 plt.title('情感分析直方图')
10 plt.show()
复制代码

 

控制台输出:

数据说明:

  • 由直方图可见,弹幕情感呈逐渐上升的趋势,说明粉丝对EDG夺冠情绪逐渐兴奋,很激动;
  • 弹幕数据中有约4500条弹幕情感分在[0.5,0.6区间内;同时,有约4800条弹幕情感分在[0.8,0.9]区间内,这个区间粉丝的情绪最亢奋,估计是夺冠时刻,哈哈哈!
  • 从区间[0.5,0.6]过渡到[0.6,0.7]以及从区间[0.8,0.9]过渡到[0.9,1.0]弹幕情绪出现下降,可能是因为在比赛中出现一些问题或者是比赛落幕了

 

5.5 关键词提取

1 from jieba import analyse
2 key_words = analyse.extract_tags(sentence=text_cut,topK=10,withWeight=True,allowPOS=())
3 print(key_words)

 

控制台输出:

数据说明:

  • 以上关键词显示,粉丝发的弹幕中“冠军”是最多的,然后是“翻译”,”我们”,“卧槽”,“小姐姐”,“EDG”,“泪目“,”圣枪哥“,”贺电“,”edg“,由此看来,EDG真的很受欢迎,翻译小姐姐也挺受欢迎的。这在上面的词云图中也可以看得出来

 

参数说明:

  • sentence是需要提取的字符串,必须是str类型,不能是list
  • topK表示提取前多少个关键字
  • withWeight表示是否返回每个关键词的权重
  • allowPOS表示允许提取的词性,默认提取地名(ns)、名词(n)、动名词(vn)、动词(v)

 

5.6 积极弹幕与消极弹幕

计算积极弹幕与消极弹幕各自的数目:

复制代码
1 pos,neg = 0,0
2 for  i in data1['emotion']:
3     if i >= 0.5:
4         pos += 1
5     else:
6         neg += 1
7 print(f'积极弹幕数据为:{pos}' + '\n' + f'消极弹幕数据为:{neg}')
复制代码

 

控制台输出:

积极弹幕数据为:17941
消极弹幕数据为:6054

 

5.7 饼图分析

复制代码
1 import matplotlib.pyplot as plt
2 
3 plt.rcParams['font.sans-serif'] = ['SimHei']
4 plt.rcParams['axes.unicode_minus'] = False
5 
6 pie_labels = 'positive','negative'
7 plt.pie([pos,neg],labels=pie_labels,autopct='%1.2f%%',shadow=True)
8 
9 plt.show()
复制代码

 

控制台输出:

由上图可见,由74.77%的弹幕数据是积极的,有25.23%的弹幕数据是消极的,总体来看,积极弹幕还是比较多的

 

5.8 消极弹幕分析

取出部分消极弹幕数据

1 data2 = data1[data1['emotion'] < 0.5]
2 data2 = data2.head()
3 print(data2)

 

控制台输出:

 

数据说明:

  • 图中的“回血”,“求生欲”等消极弹幕有可能是EDG战队或者韩国队比赛不佳造成的

 


 

六、总结

PIL库

jieba库

numpy库

pandas库

requests库

wordcloud库

matplotlib库

json,re,chardet库

snownlp情感分析库

 


 

七、完整项目及源码下载

完整项目(包括源码)获取方式:下载   https://download.csdn.net/download/qq_44000141/40776878

来源:https://www.cnblogs.com/makerchen/p/15539183.html


相关教程