期末作業搞個爬蟲給大家看看,就是大家最愛的b站的播放排行
操作如下:
1. 頁面解析
首先打開要爬取的網站:https://www.bilibili.com/v/popular/rank/all
然后右擊空白頁選擇檢查就能看到如下界面然后點擊這個箭頭所指圖標
2. 點擊箭頭所指圖標
然后點擊需要爬取的內容就可以看到標題所在的標簽和層級
這里可以看到我們需要的標題在屬性名為info的div下的a標簽中
同理找到播放量和彈幕數的標簽
3.第三步就是編寫代碼了,導入第三方運行庫先
2.然后編寫獲取頁面數據函數
3.使用beautifulsoup工具進行頁面解析
4.對需要爬取的內容進行標簽定位並循環遍歷標簽內的文本 獲取標題
獲取播放量
獲取彈幕數
5.對獲取的數據進行持久化存儲
6.進行數據清洗
查找重復值
查找是否有空值
刪除彈幕數小於20的標題(沒啥用的)
異常值觀察
查看相關系數
7數據可視化
散點圖
折線圖
扇形圖
還有回歸直線圖和條形圖
最后是線性關系圖和詞雲圖
最后的最后 給源碼給大家看看
#導入程序所需要的所有第三方運行庫
import requests
import bs4
import pandas as pd
from bs4 import BeautifulSoup
import numpy as np
import matplotlib
import seaborn as sns
from matplotlib import pyplot as plt
import re
from scipy.sparse import data
from wordcloud import WordCloud
import matplotlib.pyplot as plt
from imageio import imread
plt.rcParams['font.sans-serif'] = ['SimHei'] # 顯示中文標簽,防止畫圖出現中文字符不顯示
plt.rcParams['font.serif'] = ['KaiTi']
plt.rcParams['axes.unicode_minus'] = False
#獲取頁面數據
def getHtmlText(url):
try:
#UA偽裝
headers = {
'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'
}
html = page_text = requests.get(url = url,headers = headers)
# html.encoding = 'utf-8' #設置頁面編碼格式為utf-8防止獲取到的是亂碼
htmlText = html.text
# print(htmlText)
return htmlText
except:
print("獲取頁面數據失敗") #若出現異常打印字符串
#使用BeautifulSoup進行頁面解析
def ymjiexi(html_text):
soup = BeautifulSoup(html_text,'html.parser')
return soup
# 散點圖
def aScatter():
x = df.播放量
y = df.彈幕數
plt.xlabel('播放量')
plt.ylabel('彈幕數')
plt.scatter(x, y, color = "red", label = "點", s = 50)
plt.title("播放量與彈幕數量的散點圖")
plt.legend(loc = 'best')
plt.show()
aScatter()
# 折線圖
# 播放量與彈幕數的折線圖
def brokenLine():
dp = pd.DataFrame(pd.read_csv('b站播放量排行榜(刪除后).csv'))
print(df.head(10))
x = dp.播放量
y = dp.彈幕數
plt.xlabel("播放量")
plt.ylabel("彈幕數")
plt.plot(x, y, color = "green", label = "折線")
plt.title("播放量與彈幕數的折線圖")
plt.legend()
plt.show()
brokenLine()
#播放量與彈幕數的扇形圖
def pieChart():
dp = pd.DataFrame(pd.read_csv('b站播放量排行榜(刪除后).csv'))
x = df.播放量
y = df.彈幕數
name = [x[0], x[1], x[2], x[3], x[4]]
math = [y[0], y[1], y[2], y[3], y[4]]
explode = [0.1, 0.1, 0.1, 0.1, 0.1]
plt.pie(math, labels = name, colors = ["r", "g", "c", "b", "y"], explode = explode)
plt.axis("equal")
plt.title("b站熱榜播放量與彈幕數的扇形圖")
plt.show()
pieChart()
#播放量與彈幕數的回歸直線圖
# 回歸直線的圖
def back():
dp = pd.DataFrame(pd.read_csv('b站播放量排行榜(刪除后).csv'))
x = df.播放量
y = df.彈幕數
# X,Y為散點圖的
X = df.播放量
Y = df.彈幕數
# 先定義所需要的數據
x_i2 = 0
x_i = 0
y_i = 0
# 用mean()方法計算出x,y的均值
q = x.mean()
w = y.mean()
for i in range(7):
x_i2 = x_i + x[i] * x[i]
x_i = x_i + x[i]
y_i = y_i + y[i]
m_1 = x_i * y_i - 7 * q * w
m_2 = x_i2 - 7 * q * q
k = m_1 / m_2
# 截距
b = w - q * k
x = np.linspace(0, 7)
y = k * x + b
print("斜率k=", k, "截距b=", b)
plt.figure(figsize = (6, 4))
plt.xlabel('播放量')
plt.ylabel('彈幕數')
plt.scatter(X, Y, color = "green", label = "散點", linewidth = 2)
plt.plot(x, y, color = "blue", label = "回歸直線")
plt.title("回歸直線圖")
plt.legend()
plt.show()
back()
#對爬取內容進行定位
def Title(): #獲取標題並進行存儲
tit = [] #創建數組進行存儲
title = ymjiexi(getHtmlText(url)).select('.info > a')
for ti in title:
tit.append(ti.text)
return tit
#獲取播放量並進行存儲
def getBo():
bofan = [] #創建數組進行存儲
bo = ymjiexi(getHtmlText(url)).select('.detail-state > span:nth-of-type(1)')
for b in bo:
bof = re.findall(r'\d+\.\d+|\d+',b.text)
bofan.append(bof[0])
return bofan
def danmu():
danmus = [] #存儲彈幕數
danmu = ymjiexi(getHtmlText(url)).select('.detail-state > span:nth-of-type(2)')
for d in danmu:
bof = re.findall('\d+\.\d+|\d+',d.text)
# print(bof)
danmus.append(bof[0])
return danmus
if __name__ == '__main__':
url = 'https://www.bilibili.com/v/popular/rank/all'
ymjiexi(getHtmlText(url))
Title() #獲取標題
getBo() #獲取播放量
danmu() #獲取彈幕量
datas = [] #存儲標題和播放量
print("{:^30}\t{:^40}\t{:^30}".format( '標題', '播放量','彈幕數'))
for i in range(10):
print("{:^30}\t{:^40}\t{:^30}".format(Title()[i],getBo()[i],danmu()[i]))
datas.append([Title()[i],getBo()[i],danmu()[i]])
print(datas)
#將爬取到的內容保存到csv文件里進存儲和后續的數據清洗
df = pd.DataFrame(datas, columns = ["標題", '播放量', '彈幕數'])
df.to_csv('b站播放量排行榜.csv', index = False) #設置index = Flase防止出現未命名的列
print("爬取完畢!")
#進行數據清洗
df = pd.DataFrame(pd.read_csv('b站播放量排行榜.csv')) #導入文件
# 查找重復值
df.duplicated()
print(df.duplicated())
# 刪除無效行
df.drop('標題',axis = 1,inplace = True)
print(df.head(10))
# 查找是否有空值
print(df['標題'].isnull().value_counts())
print(df['熱度'].isnull().value_counts())
# 刪除彈幕數量小於20的標題
def drop():
drop = df.drop(index=(df.loc[(df['彈幕數']<20)].index))
print(drop)
drop.to_csv('b站播放量排行榜(刪除后).csv', index = False)
print("保存成功")
drop()
# 異常值的觀察
abnormal = df.describe()
print(abnormal)
# 查看相關系數
xishu = df.corr()
print(xishu)
#繪制條形圖
def bar():
df = pd.DataFrame(pd.read_csv('b站播放量排行榜.csv'))
x = df.播放量
y = df.彈幕數
plt.xlabel('播放量')
plt.ylabel('彈幕數')
plt.bar(x,y,color='red')
plt.title("播放量與彈幕數的條形圖")
plt.show()
bar()
# 線性關系圖
def line():
df = pd.DataFrame(pd.read_csv('b站播放量排行榜.csv'))
sns.lmplot(x = "播放量", y = "彈幕數", data = df)
plt.show()
line()
#讀取b站播放量排行榜.csv將其中的標題名稱寫到txt文本中
text = pd.read_csv("b站播放量排行榜.csv", encoding='utf-8')
with open("標題.txt",'a+', encoding='utf-8') as f:
for title in text.標題:
f.write((str(title)+'\n'))
#讀取文本
text=open('標題.txt',encoding='utf-8').read()
#詞雲的背景圖片
photo=imread('小雞.jpg')
Cyun=WordCloud(
background_color = "white",
mask = photo,
width=1000,
repeat=True,
font_path=r'simfang.ttf',
height=1600).generate(text)
plt.imshow(Cyun)
plt.axis("off")
plt.show()
#保存圖片
Cyun.to_file("標題詞雲.jpg")