爬取B站热门视频数据并对数据进行可视化呈现和可视化数据分析
(一)选题背景
随着网络的飞速发展,各各视频平台也在不断兴起,每一个视频平台也各具自己的特色,有以短视频为主的抖音,也有以二次元文化为主的B站,以搞笑视频为主的快手,它们都各具自己的特色,视频的大量发布,面向不同的人群,质量也参差不齐,经过大浪淘沙,我们可以看到一些播放量高,评论量多的优秀视频,那么我们就可以在平台上找到播放量高,高质量视频并把它们统计分析进行可视话呈现,方便人们选择视频.
(二)步骤解释
1.爬取视频数据
找到数据地址
对爬取到的数据进行解析,获取每一条视频数据信息
对数据进行保存
2.对数据进行可视化
使用flask框架,
挑选合适的Echarts图表模板
把爬取到的数据通过flask框架传进Echart模板中
挑选合适的Echarts图表模板
把爬取到的数据通过flask框架传进Echart模板中
3,可视话分析
数据分析爬取网站地址:https://api.bilibili.com/x/web-interface/popular?ps=20&pn=1
(三)具体步骤
1.找到数据地址
2.对爬取到的数据进行解析,获取每一条视频数据信息
import requests import json import csv all_data=[] def Get_data(): header={ 'user-agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 Edg/114.0.1823.37' } url='https://api.bilibili.com/x/web-interface/popular' for i in range(1,30): param={ 'ps': 20, 'pn': i } res=requests.get(url=url,headers=header,params=param) #print(res.text) Parse(res.text) res.close()
3.对数据解析
def Parse(text): dict=json.loads(text) # print(dict['data']['list']) for i in dict['data']['list']: # print(i['title']) # print(i['owner']['name']) # print(i['stat']['view']) # print(i['stat']['danmaku']) temp=(i['title'], i['owner']['name'], i['stat']['view'], i['stat']['danmaku'] ) all_data.append(temp)
4.对数据进行保存
def Save_data(all_data): with open(r'all_data1.csv',mode='w',encoding='utf-8',newline='') as fp: writer=csv.writer(fp) writer.writerow(['视频名称', '视频作者', '视频播放量', '视频评论数'] ) for i in all_data: writer.writerow(i) if __name__ == '__main__': #Get_data() #print(all_data) #Save_data(all_data=all_data) with open('all_data.csv',mode='r',encoding='utf-8') as fp: reader=csv.DictReader(fp) for i in reader: print(i)
5.对数据进行列表可视话

@app.route('/1') def demo(): data=[] with open(r'C:\Users\chase\PycharmProjects\pythonProject\flask666\all_data.csv',mode='r',encoding='utf-8') as fp: reader=csv.reader(fp) for i in reader: data.append(i) return render_template('1.html',alldata=data)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>1</title> <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"> <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script> <script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script> </head> <body> <table class="table table-striped table-bordered table-hover"> {%for i in alldata%} <tr> <td>{{ i[0] }}</td> <td>{{ i[1] }}</td> <td>{{ i[2] }}</td> <td>{{ i[3] }}</td> </tr> {%endfor%} </table> </body> </html>
6.对数据进行图表可视化

@app.route('/2') def demodemo(): title = [] up=[] view=[] comment=[] with open(r'C:\Users\chase\PycharmProjects\pythonProject\flask666\all_data.csv', mode='r', encoding='utf-8') as fp: reader = csv.DictReader(fp) for i in reader: title.append(i['视频名称']) up.append(i['up主']) view.append(i['播放量']) comment.append(i['评论数']) return render_template('2.html',title=title,view=view,comment=comment,up=up)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>2</title> <script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script> </head> <body> <div id="main" style="width: 100%;height:800px;"></div> <script type="text/javascript"> var myChart = echarts.init(document.getElementById('main')); option = { tooltip: { trigger: "axis", axisPointer: { type: "shadow" } }, dataZoom: [ { type: 'slider', show: true, start: 94, end: 100, handleSize: 8 }, { type: 'inside', start: 94, end: 100 }, { type: 'slider', show: true, yAxisIndex: 0, filterMode: 'empty', width: 12, height: '70%', handleSize: 8, showDataShadow: false, left: '93%' } ], xAxis: { type: 'category', data: {{ title|tojson }}, axisLabel:{ interval:0, rotate:60 } }, yAxis: { type: 'value' }, series: [{ data: {{ view|tojson }}, type: 'bar', showBackground: true, backgroundStyle: { color: 'rgba(180, 180, 180, 0.2)' } }] }; myChart.setOption(option); </script> </body> </html>
7.可视化分析

@app.route('/3') def echart(): title=[] view=[] comment=[] with open(r'C:\Users\chase\PycharmProjects\pythonProject\flask666\all_data.csv', mode='r', encoding='utf-8') as fp: reader = csv.DictReader(fp) for i in reader: title.append(i['视频名称']) view.append(i['播放量']) comment.append(i['评论数']) return render_template('3.html',title=title,view=view,comment=comment)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>可视化分析</title> <script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script> </head> <body> <div id="main" style="width: 100%;height:800px;"></div> <div id="main1" style="width: 100%;height:800px;"></div> <script type="text/javascript"> var myChart = echarts.init(document.getElementById('main')); var option = { title: { text: '播放量和评论数可视化' }, dataZoom: [ { type: 'slider', show: true, start: 94, end: 100, handleSize: 8 }, { type: 'inside', start: 94, end: 100 }, { type: 'slider', show: true, yAxisIndex: 0, filterMode: 'empty', width: 12, height: '70%', handleSize: 8, showDataShadow: false, left: '93%' } ], grid:{ }, tooltip: { trigger: "axis", axisPointer: { type: "shadow" } }, legend: { data:['视频播放量','视频评论数'] }, xAxis: [{ type: "category", data: {{ title| tojson }}, axisLabel: { interval: 0, show: true, formatter: function(value) { return value.split('').join('\n') } } }], yAxis: { type:'value', }, series: [{ label: { show: true, position: 'inside' }, name: '视频播放量', type: 'bar', data: {{ view|tojson }} },{ label: { show: true, position: 'inside' }, name: '视频评论数', type: 'bar', data: {{ comment|tojson }} }] }; myChart.setOption(option); </script> <script type="text/javascript"> var myChart = echarts.init(document.getElementById('main1')); var option = { title: { text: '评论数可视化' }, dataZoom: [ { type: 'slider', show: true, start: 94, end: 100, handleSize: 8 }, { type: 'inside', start: 94, end: 100 }, { type: 'slider', show: true, yAxisIndex: 0, filterMode: 'empty', width: 12, height: '70%', handleSize: 8, showDataShadow: false, left: '93%' } ], tooltip: {}, legend: { data:['视频评论数'] }, xAxis: [{ type: "category", data: {{ title| tojson }}, axisLabel: { interval: 0, show: true, formatter: function(value) { return value.split('').join('\n') } } }], yAxis: {}, series: [{ name: '视频评论数', type: 'bar', data: {{ comment|tojson }} } ] }; myChart.setOption(option); </script> </body> </html>
(四)总代码












1 import requests 2 import json 3 import csv 4 all_data=[] 5 def Get_data(): 6 header={ 7 'user-agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 Edg/114.0.1823.37' 8 } 9 url='https://api.bilibili.com/x/web-interface/popular' 10 for i in range(1,30): 11 param={ 12 'ps': 20, 13 'pn': i 14 } 15 res=requests.get(url=url,headers=header,params=param) 16 #print(res.text) 17 Parse(res.text) 18 res.close() 19 def Parse(text): 20 dict=json.loads(text) 21 # print(dict['data']['list']) 22 for i in dict['data']['list']: 23 # print(i['title']) 24 # print(i['owner']['name']) 25 # print(i['stat']['view']) 26 # print(i['stat']['danmaku']) 27 temp=(i['title'], 28 i['owner']['name'], 29 i['stat']['view'], 30 i['stat']['danmaku'] 31 ) 32 all_data.append(temp) 33 def Save_data(all_data): 34 with open(r'all_data1.csv',mode='w',encoding='utf-8',newline='') as fp: 35 writer=csv.writer(fp) 36 writer.writerow(['视频名称', 37 '视频作者', 38 '视频播放量', 39 '视频评论数'] 40 ) 41 for i in all_data: 42 writer.writerow(i) 43 44 if __name__ == '__main__': 45 #Get_data() 46 #print(all_data) 47 #Save_data(all_data=all_data) 48 with open('all_data.csv',mode='r',encoding='utf-8') as fp: 49 reader=csv.DictReader(fp) 50 for i in reader: 51 print(i) 52 53 54 from flask import Flask,render_template 55 import csv 56 57 app=Flask(__name__) 58 59 @app.route('/') 60 def hello_world(): 61 62 return '你好世界' 63 @app.route('/data') 64 def data(): 65 data = [] 66 with open(r'C:\Users\chase\PycharmProjects\pythonProject\flask666\all_data.csv', mode='r', encoding='utf-8') as fp: 67 reader = csv.reader(fp) 68 for i in reader: 69 if len(i) != 0: 70 data.append(i) 71 return render_template('data.html',data=data) 72 73 @app.route('/3') 74 def echart(): 75 title=[] 76 view=[] 77 comment=[] 78 with open(r'C:\Users\chase\PycharmProjects\pythonProject\flask666\all_data.csv', mode='r', encoding='utf-8') as fp: 79 reader = csv.DictReader(fp) 80 for i in reader: 81 title.append(i['视频名称']) 82 view.append(i['播放量']) 83 comment.append(i['评论数']) 84 return render_template('3.html',title=title,view=view,comment=comment) 85 86 @app.route('/1') 87 def demo(): 88 data=[] 89 with open(r'C:\Users\chase\PycharmProjects\pythonProject\flask666\all_data.csv',mode='r',encoding='utf-8') as fp: 90 reader=csv.reader(fp) 91 for i in reader: 92 data.append(i) 93 return render_template('1.html',alldata=data) 94 95 @app.route('/2') 96 def demodemo(): 97 title = [] 98 up=[] 99 view=[] 100 comment=[] 101 with open(r'C:\Users\chase\PycharmProjects\pythonProject\flask666\all_data.csv', mode='r', encoding='utf-8') as fp: 102 reader = csv.DictReader(fp) 103 for i in reader: 104 title.append(i['视频名称']) 105 up.append(i['up主']) 106 view.append(i['播放量']) 107 comment.append(i['评论数']) 108 return render_template('2.html',title=title,view=view,comment=comment,up=up) 109 if __name__=='__main__': 110 app.run(debug=True) 111 112 113 data.html 114 115 <!DOCTYPE html> 116 <html lang="en"> 117 <head> 118 <meta charset="UTF-8"> 119 <title>数据分析</title> 120 <!-- 新 Bootstrap4 核心 CSS 文件 --> 121 <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"> 122 123 <!-- jQuery文件。务必在bootstrap.min.js 之前引入 --> 124 <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script> 125 126 <!-- bootstrap.bundle.min.js 用于弹窗、提示、下拉菜单,包含了 popper.min.js --> 127 <script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script> 128 129 <!-- 最新的 Bootstrap4 核心 JavaScript 文件 --> 130 <script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script> 131 132 133 </head> 134 <body> 135 <table class="table table-striped table-bordered table-hover"> 136 {% for i in data %} 137 <tr> 138 <td>{{ i[0] }}</td> 139 <td>{{ i[1] }}</td> 140 <td>{{ i[2] }}</td> 141 <td>{{ i[3] }}</td> 142 </tr> 143 {%endfor%} 144 </table> 145 </body> 146 </html> 147 148 149 1.html 150 151 <!DOCTYPE html> 152 <html lang="en"> 153 <head> 154 <meta charset="UTF-8"> 155 <title>1</title> 156 <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"> 157 <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script> 158 <script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script> 159 <script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script> 160 </head> 161 <body> 162 <table class="table table-striped table-bordered table-hover"> 163 {%for i in alldata%} 164 <tr> 165 <td>{{ i[0] }}</td> 166 <td>{{ i[1] }}</td> 167 <td>{{ i[2] }}</td> 168 <td>{{ i[3] }}</td> 169 </tr> 170 {%endfor%} 171 </table> 172 </body> 173 </html> 174 175 2.html 176 177 <!DOCTYPE html> 178 <html lang="en"> 179 <head> 180 <meta charset="UTF-8"> 181 <title>2</title> 182 <script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script> 183 </head> 184 <body> 185 <div id="main" style="width: 100%;height:800px;"></div> 186 <script type="text/javascript"> 187 var myChart = echarts.init(document.getElementById('main')); 188 option = { 189 tooltip: { 190 trigger: "axis", 191 axisPointer: { 192 type: "shadow" 193 } 194 }, 195 dataZoom: [ 196 { 197 type: 'slider', 198 show: true, 199 start: 94, 200 end: 100, 201 handleSize: 8 202 }, 203 { 204 type: 'inside', 205 start: 94, 206 end: 100 207 }, 208 { 209 type: 'slider', 210 show: true, 211 yAxisIndex: 0, 212 filterMode: 'empty', 213 width: 12, 214 height: '70%', 215 handleSize: 8, 216 showDataShadow: false, 217 left: '93%' 218 } 219 ], 220 xAxis: { 221 type: 'category', 222 data: {{ title|tojson }}, 223 axisLabel:{ 224 interval:0, 225 rotate:60 226 } 227 }, 228 yAxis: { 229 type: 'value' 230 }, 231 series: [{ 232 data: {{ view|tojson }}, 233 type: 'bar', 234 showBackground: true, 235 backgroundStyle: { 236 color: 'rgba(180, 180, 180, 0.2)' 237 } 238 }] 239 }; 240 241 myChart.setOption(option); 242 </script> 243 </body> 244 </html> 245 246 3.html 247 248 <!DOCTYPE html> 249 <html lang="en"> 250 <head> 251 <meta charset="UTF-8"> 252 <title>可视化分析</title> 253 <script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script> 254 </head> 255 <body> 256 <div id="main" style="width: 100%;height:800px;"></div> 257 <div id="main1" style="width: 100%;height:800px;"></div> 258 <script type="text/javascript"> 259 var myChart = echarts.init(document.getElementById('main')); 260 var option = { 261 title: { 262 text: '播放量和评论数可视化' 263 }, 264 dataZoom: [ 265 { 266 type: 'slider', 267 show: true, 268 start: 94, 269 end: 100, 270 handleSize: 8 271 }, 272 { 273 type: 'inside', 274 start: 94, 275 end: 100 276 }, 277 { 278 type: 'slider', 279 show: true, 280 yAxisIndex: 0, 281 filterMode: 'empty', 282 width: 12, 283 height: '70%', 284 handleSize: 8, 285 showDataShadow: false, 286 left: '93%' 287 } 288 ], 289 grid:{ 290 291 }, 292 tooltip: { 293 trigger: "axis", 294 axisPointer: { 295 type: "shadow" 296 } 297 }, 298 legend: { 299 data:['视频播放量','视频评论数'] 300 }, 301 xAxis: [{ 302 type: "category", 303 data: {{ title| tojson }}, 304 axisLabel: { 305 interval: 0, 306 show: true, 307 formatter: function(value) { 308 return value.split('').join('\n') 309 } 310 } 311 }], 312 yAxis: { 313 type:'value', 314 315 }, 316 series: [{ 317 label: { 318 show: true, 319 position: 'inside' 320 }, 321 name: '视频播放量', 322 type: 'bar', 323 data: {{ view|tojson }} 324 },{ 325 label: { 326 show: true, 327 position: 'inside' 328 }, 329 name: '视频评论数', 330 type: 'bar', 331 data: {{ comment|tojson }} 332 }] 333 }; 334 335 myChart.setOption(option); 336 </script> 337 <script type="text/javascript"> 338 var myChart = echarts.init(document.getElementById('main1')); 339 340 var option = { 341 title: { 342 text: '评论数可视化' 343 }, 344 dataZoom: [ 345 { 346 type: 'slider', 347 show: true, 348 start: 94, 349 end: 100, 350 handleSize: 8 351 }, 352 { 353 type: 'inside', 354 start: 94, 355 end: 100 356 }, 357 { 358 type: 'slider', 359 show: true, 360 yAxisIndex: 0, 361 filterMode: 'empty', 362 width: 12, 363 height: '70%', 364 handleSize: 8, 365 showDataShadow: false, 366 left: '93%' 367 } 368 ], 369 tooltip: {}, 370 legend: { 371 data:['视频评论数'] 372 }, 373 xAxis: [{ 374 type: "category", 375 data: {{ title| tojson }}, 376 axisLabel: { 377 interval: 0, 378 show: true, 379 formatter: function(value) { 380 return value.split('').join('\n') 381 } 382 } 383 }], 384 yAxis: {}, 385 series: [{ 386 name: '视频评论数', 387 type: 'bar', 388 data: {{ comment|tojson }} 389 } 390 ] 391 }; 392 393 myChart.setOption(option); 394 </script> 395 </body> 396 </html>