Python⽹络爬⾍——爬取b站播放排⾏榜
⼀、选题的背景
为什么要选择此选题?要达到的数据分析的预期⽬标是什么?(10 分)
现在⼤家都很喜欢b站,我也作为b站⽼⽤户,所以这个爬⾍通过爬取b站播放排⾏榜信息,来看看最近必看的有⽤的好玩的任何视频。⼆、主题式⽹络爬⾍设计⽅案(10 分)
1.主题式⽹络爬⾍名称:爬取b站热门播放排⾏榜
2.主题式⽹络爬⾍爬取的内容与数据特征分析:
通过request爬取b站热门视频排⾏榜的排名、播放量、弹幕数
使⽤BeautifulSoup分析⽹页结构定位内容所在标签获取数据
使⽤Numpy对获取的数据进⾏数据清洗
使⽤matplotlib对数据进⾏可视化处理
3.主题式⽹络爬⾍设计⽅案概述:
数据获取需要分为⼏个步骤实现:
1)通过request获取⽹页资源
2)使⽤BuautifulSoup解析⽹页,定位爬取资源
3)编写代码将数据保存到csv⽂件中
三、主题页⾯的结构特征分析(10 分)
数据来源:
Htmls页⾯解析
(1) 需要爬取的⽹页
(1) 按下F12打开开发者模式
(1) 按下ctrl + shift + c然后点击需要爬取的内容
(1) 从最下⾯的层级列表中可以看到我们需要爬取的标题最终在a.title这个标签下⾯
(5) 同理到播放量和弹幕数
四、⽹络爬⾍程序设计
1.
数据爬取及采集:
---------------------------------------------------------------------------------------------
导⼊程序所需要的所有第三⽅运⾏库
1import requests #获取页⾯数据
2import pandas as pd #⽤于数据清洗
3from bs4 import BeautifulSoup #解析页⾯
4import numpy as np
5import matplotlib #绘图库
6import seaborn as sns
7from matplotlib import pyplot as plt
8import re #⽤于正则表达式
9from scipy.sparse import data
10import matplotlib.pyplot as plt
11from imageio import imread
12from wordcloud import WordCloud
获取页⾯响应数据
1#获取页⾯响应数据
2
3def  getHtmlText(url):
4try:
5#UA伪装
6        headers = {
7'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62'
8        }
9        html = page_text = (url = url,headers = headers)
10# ding = 'utf-8' #设置页⾯编码格式为utf-8防⽌获取到的是乱码
11        htmlText =
12# print(htmlText)
13return htmlText
14except:
15print("获取页⾯数据失败") #若出现异常打印字符串
BeautifulSoup进⾏页⾯解析
python正则表达式爬虫
1#使⽤BeautifulSoup进⾏页⾯解析
2def ymjiexi(html_text):
3    soup = BeautifulSoup(html_text,'html.parser')
4return soup
对爬取内容进⾏定位
1#对爬取内容进⾏定位
2def  Title(): #获取标题并进⾏存储
3    tit = [] #创建数组进⾏存储
4    title = ymjiexi(getHtmlText(url)).select('.info > a')
5for ti in title:
6        tit.)
7return tit
8#获取播放量并进⾏存储
9def getBo():
10    bofan = [] #创建数组进⾏存储
11    bo = ymjiexi(getHtmlText(url)).select('.detail-state > span:nth-of-type(1)')
12for b in bo:
13        bof = re.findall(r'\d+\.\d+|\d+',b.text)
14        bofan.append(bof[0])
15return bofan
获取弹幕并进⾏存储
1#获取弹幕并进⾏存储
2def  danmu():
3    danmus = [] #存储弹幕数
4    danmu = ymjiexi(getHtmlText(url)).select('.detail-state > span:nth-of-type(2)')
5for d in danmu:
6        bof = re.findall('\d+\.\d+|\d+',d.text)
7if float(bof[0]) < 10:
8            bof[0] = float(bof[0]) * 10000 #如果弹幕数量
9        danmus.append(bof[0])
10return danmus
运⾏得到结果
1if__name__ == '__main__':
2    url = 'www.bilibili/v/popular/rank/all'
3    ymjiexi(getHtmlText(url))
4    Title() #获取标题
5    getBo() #获取播放量
6    danmu() #获取弹幕量
7    datas = [] #存储标题和播放量
8print("{:^10}\t{:^30}\t{:^40}\t{:^30}".format( '排名','标题', '播放量','弹幕数'))
9for i in range(10):
10print("{:^10}\t{:^30}\t{:^40}\t{:^30}".format(i+1,Title()[i],getBo()[i],danmu()[i]))
11        datas.append([i+1,Title()[i],getBo()[i],danmu()[i]])
12对数据进⾏清理:
13
14
15 df = pd.ad_csv('b站播放量排⾏榜.csv')) #导⼊⽂件
16#查重复值
17 df.duplicated()
18print(df.duplicated())
19删除⽆效⾏列
20
21#  删除⽆效列
22
23 df.drop('标题',axis = 1,inplace = True)
24
25print(df.head(10))
26
27# 查是否有空值
28
29print(df['播放量'].isnull().value_counts())
30
31print(df['弹幕数'].isnull().value_counts())
32
33
34
35异常值的观察
36
37
38
39 abnormal = df.describe()
40
41
42
43print(abnormal)
44
45# 查看相关系数
46
47 xishu = df.corr()
48
49print(xishu)
数据分析与可视化:
散点图
1def  aScatter():
2    Params['font.sans-serif'] = ['SimHei']  # 显⽰中⽂标签,防⽌数据可视化总出现中⽂字符不显⽰
3    x = df.播放量
4    y = df.弹幕数
5    plt.xlabel('播放量')
6    plt.ylabel('弹幕数')
7    plt.scatter(x, y, color = "red", label = "点", s = 50)
8    plt.title("播放量与弹幕数量的散点图")
9    plt.legend(loc = 'best')
10    plt.show()
11 aScatter()
折线图
1#  折线图
2#    排名与弹幕数的折线图
3def  brokenLine():
4    Params['font.sans-serif'] = ['SimHei']  # 显⽰中⽂标签,防⽌数据可视化总出现中⽂字符不显⽰
5    dp = pd.ad_csv('b站播放量排⾏榜.csv'))
6    x = dp.排名
7    y = dp.弹幕数
8    plt.xlabel("排名")
9    plt.ylabel("弹幕数")
10    plt.plot(x, y, color = "green", label = "折线")
11    plt.title("播放量与弹幕数的折线图")
12    plt.legend()
13    plt.show()
14 brokenLine()
扇形图
1#播放量与弹幕数的扇形图
2def  pieChart():
3    dp = pd.ad_csv('b站播放量排⾏榜(删除后).csv'))
4    Params['font.sans-serif'] = ['SimHei']  # 显⽰中⽂标签,防⽌数据可视化总出现中⽂字符不显⽰
5    x = df.播放量
6    y = df.弹幕数
7    name = [x[0], x[1], x[2], x[3], x[4]]
8    math = [y[0], y[1], y[2], y[3], y[4]]
9    explode = [0.1, 0.1, 0.1, 0.1, 0.1]
10    plt.pie(math, labels = name, colors = ["r", "g", "c", "b", "y"], explode = explode)
11    plt.axis("equal")
12    plt.title("b站热榜播放量与弹幕数的扇形图")
13    plt.show()
14 pieChart()
回归直线图
1def  back():
2    dp = pd.ad_csv('b站播放量排⾏榜.csv'))
3    Params['font.sans-serif'] = ['SimHei']  # 显⽰中⽂标签,防⽌数据可视化总出现中⽂字符不显⽰
4    Params['font.serif'] = ['KaiTi']
5    Params['axes.unicode_minus'] = False
6    x = df.排名
7    y = df.弹幕数
8# X,Y为散点图的
9    X = df.排名
10    Y = df.弹幕数
11# 先定义所需要的数据
12    x_i2 = 0
13    x_i = 0
14    y_i = 0
15# ⽤mean()⽅法计算出x,y的均值
16    q = x.mean()
17    w = y.mean()
18for i in range(7):
19        x_i2 = x_i + x[i] * x[i]
20        x_i = x_i + x[i]
21        y_i = y_i + y[i]
22    m_1 = x_i * y_i - 7 * q * w
23    m_2 = x_i2 - 7 * q * q
24    k = m_1 / m_2
25# 截距
26    b = w - q * k
27    x = np.linspace(0, 7)
28    y = k * x + b
29print("斜率k=", k, "截距b=", b)
30    plt.figure(figsize = (6, 4))
31    plt.xlabel('排名')
32    plt.ylabel('弹幕数')
33    plt.scatter(X, Y, color = "green", label = "散点", linewidth = 2)
34    plt.plot(x, y, color = "blue", label = "回归直线")
35    plt.title("回归直线图")
36    plt.legend()
37    plt.show()
38 back()