爬取bilibili综合热门排行榜及数据分析

 

 

爬取bilibili综合热门排行榜及数据分析

 

一、  选题背景

         根据2019年第44次《中国互联网络发展状况统计报告》显示,至2019年6月,我国网民规模为8.54亿,Z世代(10-29岁)网民占比41.5%,约为3. 55亿人。B站在Z世代中的人口渗透率约为12.8%,渗透率将持续提高,增长潜力巨大。在QuestMobile统计的Z世代偏爱APP榜单中,B站独占鳌头。Z世代是生长于移动互联网的一代,恰逢经济腾飞、消费升级,而且经济水平和消费意识都较前代更强,且Z世代大多还未负担起沉重的现实与家庭压力,付费能力和付费意愿较高,版权意识较上代人显著提升。随着Z世代收入和消费能力的不断增强,中国泛娱乐市场发展前景十分光明。因此通过爬取b站近期热门排行榜得到的数据通过可视化分析可以了解人们的喜好,更方便的定位人们的需求。

二、主题式网络爬虫设计方案

        1.主题式网络爬虫名称:

            爬取bilibili综合热门排行榜及数据分析

        2.主题式网络爬虫爬取的内容

          爬取近期热门视频的标题,up主,播放数,评论数。

       3.主题式网络爬虫设计方案概述 

          通过页面使用开发者工具找到network中的XHR通过查看Headers了解网页的请求方式,并且获取URL。爬取数据之后,通过执行dict=json.loads(text)操作,把数据转化为字典方便数据提取。通过执行

        print(dict)的操作找到所需要爬取的内容,并且将其保存csv文件中。进行数据可视化分析。

三、主题页面的结构特征分析

 1.主题页面的结构与特征分析

从所需爬取的页面中 , 通过页面使用开发者工具(F12)找到network中的XHR通过查看Headers了解网页的请求方式,并且获取URL(https://api.bilibili.com/x/web-interface/popular?ps=20&pn=1)

 

 

 

 

 

 

json数据结构

 

 

 

 所需要爬取的数据都存放在这个接口里面。

 

 

 

 

 

 2.页面解析

 通过对比参数发现只有'pn'这个参数不同,刷新页面滑到视频的底部,发现'pn'值为11。pn代表页数,所以热门视频共有十一页。下一步开始爬虫。

 

 

 

用json方法把request返回的格式转译为字典,通过执行dict=json.loads(text)操作,这样更方便数据提取。通过执行 print(dict)的操作找到所需要爬取的内容。

(PS:因为动态加载的原因,爬取的内容可能和之后的可视化有点差异,但不影响结果的展示)

3.节点(标签)查找方法与遍历方法

用json方法把request返回的格式转译为字典,从上图输出结果可是看出数据是来自data,list,遍历字典for i in dict['data']['list']:。然后执行print(i)找到这些所需要的key值。后遍历这些key值。

 

 

 

 

 

 

 

四、网络爬虫程序设计

爬虫程序主体要包括以下各部分。

1.数据爬取与采集

 

 1 #导入所需要的库
 2 import requests
 3 import json
 4 import csv
 5 #爬虫部分
 6 #1.数据是动态加载的,所以需要寻找数据地址
 7 def Get_data():
 8     #处理一个小小的反爬,伪装成浏览器发送请求。
 9     header={
10         'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
11     }
12     url='https://api.bilibili.com/x/web-interface/popular'
13     #从页面分析知道热门数据共有11页
14     for i in range(1,12):
15         #把URL的参数封装成一个字典
16         param={
17             'ps': 20,
18             'pn': i
19         }
20         res=requests.get(url=url,headers=header,params=param)
21         print(res.text)
22        #Parse(res.text)#下一步需要利用的函数
23         res.close()#关闭对网页的爬取
24         
25 if __name__ == '__main__':
26     Get_data()

 

 爬取成功结果截图如下:

 2.提取所需的数据,并存储

 

 1 #2.对爬取到的数据进行解析,获取每一条视频数据的标题,Up主,播放量,评论数
 2 
 3 #对所有视频的数据都解析,每一条数据以元组的形式保存在列表中 
 4 all_data=[]
 5 def Parse(text):
 6     dict=json.loads(text)#把数据转化为字典方便数据提取
 7    # print(dict['data']['list'])
 8 
 9     for i in dict['data']['list']:
10         # print(i['title'])#标题
11         # print(i['owner']['name'])#up主
12         # print(i['stat']['view'])#播放量
13         # print(i['stat']['danmaku'])#评论数
14         
15         temp=(i['title'],i['owner']['name'],i['stat']['view'],i['stat']['danmaku'])
16         all_data.append(temp)
17         
18 #3.对数据进行保存
19 def Save_data(all_data):
20     with open(r'all_data.csv',mode='w',encoding='utf-8') as fp:
21         writer=csv.writer(fp)#创建一个csv的写对象
22         writer.writerow(['视频名称','up主','播放量','评论数'])#写一行数据作为数据头部
23         for i in all_data:
24             writer.writerow(i)#把all_data的数据写进去       
25        
26                      
27 if __name__ == '__main__':
28     Get_data()
29     #print(all_data)
30     Save_data(all_data=all_data)
31     

 

提取数据截图如下图:

 

 生成的csv如下图:

 

 

 3.数据清洗

获取的数据较完整,没有出现重复和空行情况。故不需要数据清洗。

 

4.绘制频率直方图

 1 import pandas as pd
 2 import matplotlib.pyplot as plt
 3 import numpy as np
 4 import matplotlib
 5 import seaborn as sns
 6 from sklearn import datasets
 7 from sklearn.linear_model import LinearRegression
 8 from sklearn.datasets import load_boston
 9 import jieba
10 from pylab import *
11 from wordcloud import WordCloud
12 
13 
14 #评论数的频率直方图
15 %matplotlib inline
16 plt.rcParams['font.sans-serif'] = ['SimHei']
17 plt.rcParams['axes.unicode_minus'] = False
18 df=pd.read_csv('C:/Users/10365/Desktop/python期末作业/all_data.csv')
19 plt.figure
20 
21 sns.distplot(df['评论数'].values,hist=True, kde=True,axlabel='tip',rug=False,fit=None,hist_kws = {'color':'b','label':'评论数'}, kde_kws={'color':'b'})
22 plt.title("评论数的频率直方图",fontsize=16)
23 plt.legend()
24 plt.xlabel('评论数')
25 plt.ylabel('频率')
26 plt.grid()
27 
28 
29 
30 #播放量的频率直方图
31 sns.distplot(df['播放量'].values,hist=True, kde=True,axlabel='tip',rug=False,fit=None,hist_kws = {'color':'b','label':'播放量'}, kde_kws={'color':'b'})
32 plt.title("播放量的频率直方图",fontsize=16)
33 plt.legend()
34 plt.ylabel('')
35 plt.grid()

 

 

 

 

5.绘制柱形图

 

 1 #TOP35的UP主与播放量的柱形图
 2 data=np.array(df['播放量'][0:35])
 3 index=np.array(df['up主'][0:35])
 4 print(data)
 5 print(index)
 6 plt.ylabel('播放量(百万)')
 7 
 8 plt.title("TOP35的UP主与播放量的柱形图",fontsize=16)
 9 s = pd.Series(data, index)
10 
11 s.plot(kind='bar')
12 plt.savefig('TOP35的UP主与播放量的柱形图.jpg')
13 
14 
15 
16 
17 #TOP35的UP主与评论数的柱形图
18 data=np.array(df['评论数'][0:35])
19 index=np.array(df['up主'][0:35])
20 print(data)
21 print(index)
22 plt.ylabel('评论数')
23 
24 s = pd.Series(data, index)
25 
26 plt.title("TOP35的UP主与评论数的柱形图",fontsize=16)
27 
28 s.plot(kind='bar')
29 
30 #数据持久化
31 plt.savefig('TOP35UP主与评论数的柱形图.jpg')

 

 

 

 

 6.绘制散点图

 1 #播放量与评论数关系的散点图
 2 x=df['播放量'].values
 3 
 4 y=df['评论数'].values
 5 
 6 plt.figure
 7 
 8 size=120
 9 
10 plt.xlabel('播放量(百万)')
11 
12 plt.ylabel('评论数')
13 plt.scatter(x/1,y,size,color='g',label='播放评论关系')
14 plt.legend(loc=2)
15 plt.grid()
16 plt.title("播放量与评论数关系的散点图",fontsize=16)
17 plt.show()

 

 

 

 

 

 7.数据分析,回归方程

 1 #计算回归方程系数和回归方程截距
 2 predict_model = LinearRegression()
 3 predict_model.fit(x.reshape(-1, 1),y)
 4 np.set_printoptions(precision = 3, suppress = True)
 5 print("回归方程系数{}".format(predict_model.coef_))
 6 print("回归方程截距{0:2f}".format(predict_model.intercept_))
 7 
 8 
 9 
10 #播放评论关系回归方程图
11 plt.scatter(x,y,size,color='g',label='播放评论关系')
12 yfit = [809.206980 + 0.002 * xi for xi in x]
13 plt.plot(x, yfit, color="r")
14 plt.ylabel('评论数')
15 plt.xlabel('播放量(百万)')
16 plt.show()

 

 

 8.绘制词云

 1 import jieba
 2 from pylab import *
 3 from wordcloud import WordCloud
 4 text = '  '
 5 a=''
 6 df=pd.read_csv('C:/Users/10365/Desktop/python期末作业/all_data.csv')
 7 for line in df['视频名称']:
 8     a+= line
 9     text+=a
10 # 使用jieba模块将字符串分割为单词列表
11 cut_text = '    '.join(jieba.cut(text))
12 color_mask = imread('C:/Users/10365/Desktop/python期末作业/python截图图片/书本.jpg')  #设置背景图
13 cloud = WordCloud( 
14     background_color = 'white',
15     # 对中文操作必须指明字体
16     font_path='C:/Windows/Fonts/优设标题黑_猫啃网.ttf',
17     mask = color_mask,
18     max_words = 50,
19     max_font_size = 200
20     ).generate(cut_text)
21 
22 # 保存词云图片
23 cloud.to_file('ciwordcloud.jpg')
24 plt.imshow(cloud)
25 plt.axis('off')
26 plt.show()

 

 9.数据持久化

生成CSV文件

将数据可视化的图片保存成jpg的形式

通过  #例如  plt.savefig('词云.jpg') 实现数据可视化

 

 

 10.完整代码

 

  1 #导入所需要的库
  2 import requests
  3 import json
  4 import csv
  5 
  6 #爬虫部分
  7 #1.数据是动态加载的,所以需要寻找数据地址
  8 def Get_data():
  9     header={
 10         'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
 11     }
 12     url='https://api.bilibili.com/x/web-interface/popular'
 13     for i in range(1,12):
 14         param={
 15             'ps': 20,
 16             'pn': i
 17         }
 18         res=requests.get(url=url,headers=header,params=param)
 19         #print(res.text)
 20         Parse(res.text)
 21         res.close()
 22         
 23 #2.对爬取到的数据进行解析,获取每一条视频数据的标题,Up主,播放量,评论数
 24 
 25 #对所有视频的数据都解析,每一条数据以元组的形式保存在列表中 
 26 all_data=[]
 27 def Parse(text):
 28     dict=json.loads(text)#把数据转化为字典方便数据提取
 29    # print(dict['data']['list'])
 30 
 31     for i in dict['data']['list']:
 32         # print(i['title'])#标题
 33         # print(i['owner']['name'])#up主
 34         # print(i['stat']['view'])#播放量
 35         # print(i['stat']['danmaku'])#评论数
 36         
 37         temp=(i['title'],i['owner']['name'],i['stat']['view'],i['stat']['danmaku'])
 38         all_data.append(temp)
 39         
 40 #3.对数据进行保存
 41 
 42 def Save_data(all_data):
 43     with open(r'all_data.csv',mode='w',encoding='utf-8') as fp:
 44         writer=csv.writer(fp)#创建一个csv的写对象
 45         writer.writerow(['视频名称','up主','播放量','评论数'])#写一行数据作为数据头部
 46         for i in all_data:
 47             writer.writerow(i)#把all_data的数据写进去       
 48  
 49 
 50     
 51 if __name__ == '__main__':
 52     Get_data()
 53     #print(all_data)
 54     Save_data(all_data=all_data)
 55     
 56 
 57 
 58  #数据可视化部分      
 59 
 60 import pandas as pd
 61 
 62 import matplotlib.pyplot as plt
 63 
 64 import numpy as np
 65 
 66 import matplotlib
 67 
 68 import seaborn as sns
 69 
 70 
 71 #评论数的频率直方图
 72 
 73 %matplotlib inline
 74 plt.rcParams['font.sans-serif'] = ['SimHei']
 75 plt.rcParams['axes.unicode_minus'] = False
 76 df=pd.read_csv('C:/Users/10365/Desktop/python期末作业/all_data.csv')
 77 plt.figure
 78 
 79 sns.distplot(df['评论数'].values,hist=True, kde=True,axlabel='tip',
 80              rug=False,fit=None,hist_kws = {'color':'b','label':'评论数'}, 
 81              kde_kws={'color':'b'})
 82 
 83 plt.legend()
 84 plt.xlabel('评论数')
 85 plt.ylabel('频率')
 86 plt.grid()
 87     
 88 
 89     
 90 #播放量的频率直方图
 91 
 92 sns.distplot(df['播放量'].values,hist=True, kde=True,axlabel='tip',rug=False,
 93              fit=None,hist_kws = {'color':'b','label':'播放量'}, 
 94              kde_kws={'color':'b'})
 95 
 96 plt.legend()
 97 
 98 plt.ylabel('')
 99 
100 plt.grid()    
101     
102 
103     
104 #播放量与评论数关系的散点图
105 
106 x=df['播放量'].values
107 
108 y=df['评论数'].values
109 
110 plt.figure
111 
112 size=120
113 
114 plt.xlabel('播放量(百万)')
115 
116 plt.ylabel('评论数')
117 plt.scatter(x/1,y,size,color='g',label='播放评论关系')
118 
119 plt.legend(loc=2)
120 plt.title("播放量与评论数关系的散点图",fontsize=16)
121 plt.grid()
122 
123 plt.show()    
124     
125 
126 #TOP35的UP主与播放量的柱形图
127 
128 data=np.array(df['播放量'][0:35])
129 index=np.array(df['up主'][0:35])
130 print(data)
131 print(index)
132 plt.ylabel('播放量(百万)')
133 
134 plt.title("TOP35的UP主与播放量的柱形图",fontsize=16)
135 s = pd.Series(data, index)
136 
137 s.plot(kind='bar')
138 plt.savefig('TOP35的UP主与播放量的柱形图.jpg')
139 
140 
141 
142 #TOP35的UP主与评论数的柱形图
143 
144 data=np.array(df['评论数'][0:35])
145 index=np.array(df['up主'][0:35])
146 print(data)
147 print(index)
148 plt.ylabel('评论数')
149 
150 s = pd.Series(data, index)
151 
152 plt.title("TOP35的UP主与评论数的柱形图",fontsize=16)
153 
154 s.plot(kind='bar')
155 
156 #数据持久化
157 plt.savefig('TOP35UP主与评论数的柱形图.jpg')
158 
159 
160     
161 #数据分析,回归方程   
162 
163 from sklearn import datasets
164 
165 from sklearn.linear_model import LinearRegression
166 
167 from sklearn.datasets import load_boston
168 
169 import pandas as pd
170 
171 
172 #计算回归方程系数和回归方程截距
173 
174 predict_model = LinearRegression()
175 predict_model.fit(x.reshape(-1, 1),y)
176 np.set_printoptions(precision = 3, suppress = True)
177 print("回归方程系数{}".format(predict_model.coef_))
178 print("回归方程截距{0:2f}".format(predict_model.intercept_))
179 
180 
181 #播放评论关系回归方程图
182 
183 plt.scatter(x,y,size,color='g',label='播放评论关系')
184 yfit = [809.206980 + 0.002 * xi for xi in x]
185 plt.plot(x, yfit, color="r")
186 
187 plt.ylabel('评论数')
188 
189 plt.xlabel('播放量(百万)')
190 
191 plt.title("播放评论关系回归方程图",fontsize=16)
192 
193 plt.show()
194 
195 plt.savefig('播放评论关系回归方程图.jpg')
196 
197 
198 
199 #绘制词云,查看出现最多的词语
200 
201 import jieba
202 from pylab import *
203 from wordcloud import WordCloud
204 text = '  '
205 a=''
206 df=pd.read_csv('C:/Users/10365/Desktop/python期末作业/all_data.csv')
207 for line in df['视频名称']:
208     a+= line
209     text+=a
210 
211 # 使用jieba模块将字符串分割为单词列表
212 cut_text = '    '.join(jieba.cut(text))
213 #设置背景图
214 color_mask = imread('C:/Users/10365/Desktop/python期末作业/python截图图片/书本.jpg')  
215 
216 cloud = WordCloud( 
217     
218     background_color = 'white',
219     # 对中文操作必须指明字体
220     font_path='C:/Windows/Fonts/优设标题黑_猫啃网.ttf',
221     mask = color_mask,
222     max_words = 50,
223     max_font_size = 200
224     ).generate(cut_text)
225 
226 # 保存词云图片
227 cloud.to_file('ciwordcloud.jpg')
228 plt.imshow(cloud)
229 plt.axis('off')
230 plt.show()

 

 

五、总结

1.经过对主题数据的分析与可视化,可以得到哪些结论?是否达到预期的目标? 

  结论: (1)通过近期热门视频排行榜数据爬取得知播放量最高的up主是龙馍馍,说明人们对这类视频的关注度高

              (2)通过近期热门视频排行榜数据爬取并结合词云得知评论数最高的是原神官方账号,说明人们对该视频的讨论激烈。

               因为缺少分区等方面的信息,不能更高效的分析出哪类视频在受众方面的情况,不能清楚分析出这些列别视频的受欢迎程度。

2.在完成此设计过程中,得到哪些收获?以及要改进的建议?

      通过爬取bilibili近期热门排行榜,在项目代码编写阶段巩固了基础知识,并且通过网上的视频了解到对爬取页面和解析页面的多种方法,如(requests模块,bs4,json等)所以爬虫方面进展还是比较顺利的。但是由于基础的原因在数据可视化的实现中还是比较吃力的,参考了很多种实现方法。数据可视化这方面进展比较缓慢拉下完成项目的进度。

      日后要加强对绘图库的理解与使用,通过各种实战来熟练。

 

posted @ 2021-12-28 22:09  胡振毅  阅读(2360)  评论(0编辑  收藏  举报