1.數(shù)據(jù)抓取
數(shù)據(jù)集的獲取是我們進(jìn)行數(shù)據(jù)分析的第一步?,F(xiàn)在獲取數(shù)據(jù)的主要途徑一般為:現(xiàn)成數(shù)據(jù);自己寫(xiě)爬蟲(chóng)去爬取數(shù)據(jù);使用現(xiàn)有的爬蟲(chóng)工具爬取所需內(nèi)容,保存到數(shù)據(jù)庫(kù),或以文件的形式保存到本地。
推薦閱讀:Python 靜態(tài)爬蟲(chóng)、Python Scrapy網(wǎng)絡(luò)爬蟲(chóng)
爬蟲(chóng)的設(shè)計(jì)思路
- 首先確定需要爬取網(wǎng)頁(yè) URL 地址
- 通過(guò) HTTP/HTTPS 協(xié)議來(lái)獲取相應(yīng)的 HTML 頁(yè)面
- 提取 HTML 頁(yè)面里有用的數(shù)據(jù)
a. 如果是需要的數(shù)據(jù)就保存起來(lái)
b. 如果是頁(yè)面里的其他 URL,那就繼續(xù)執(zhí)行第二步。
爬蟲(chóng)基本流程
發(fā)起請(qǐng)求 通過(guò)HTTP庫(kù)向目標(biāo)站點(diǎn)發(fā)起請(qǐng)求,就是發(fā)送一個(gè) Request,請(qǐng)求可以包含額外的 header 等信息,等待服務(wù)器的響應(yīng) 獲取響應(yīng)內(nèi)容 如果服務(wù)器正常響應(yīng),會(huì)得到一個(gè) Reponse, Reponse 的內(nèi)容便是所要獲取的頁(yè)面內(nèi)容,類型可能有 HTML,json 字符串,二進(jìn)制數(shù)據(jù)(如圖片視頻)等類型。 解析內(nèi)容 得到的內(nèi)容可能是 HTML,可以用正則表達(dá)式,網(wǎng)頁(yè)解析庫(kù)進(jìn)行解析,可能是 json,可以直接轉(zhuǎn)為 JSON 解析對(duì)象解析,可能是二進(jìn)制數(shù)據(jù),可以做保存或者進(jìn)一步處理。 保存數(shù)據(jù)保存的形式多種多樣,可以保存成文本,也可以保存到數(shù)據(jù)庫(kù),或者保存特定格式文件
反爬蟲(chóng)機(jī)制與對(duì)策
機(jī)制
- 通過(guò)分析用戶請(qǐng)求的Headers信息進(jìn)行反爬蟲(chóng)。網(wǎng)站中應(yīng)用的最多
- 通過(guò)驗(yàn)證用戶行為進(jìn)行反爬蟲(chóng),不如通過(guò)判斷同一個(gè)ip在短時(shí)間內(nèi)是否頻繁訪問(wèn)對(duì)應(yīng)網(wǎng)站等進(jìn)行分析。
- 通過(guò)動(dòng)態(tài)頁(yè)面增加爬取的難度,達(dá)到反爬蟲(chóng)目的。
對(duì)策
- 在爬蟲(chóng)中構(gòu)造這些用戶請(qǐng)求的 headers 信息,以此將爬蟲(chóng)偽裝成瀏覽器
- 使用代理服務(wù)器并經(jīng)常切換代理服務(wù)器方式,一般就能夠攻克限制。
- 利用一些軟件,比如selenium+phantomJS就可以攻克 反爬蟲(chóng)的手段 :user-agent、代理、驗(yàn)證碼、動(dòng)態(tài)數(shù)據(jù)加載、加密數(shù)據(jù)
數(shù)據(jù)的選擇與處理
- 網(wǎng)頁(yè)文本,如HTML文檔 json格式文本 ;
- 圖片,獲取到的是二進(jìn)制文件保存為圖片格式 ;
- 視頻 獲取的二進(jìn)制文件保存為視頻格式即可;
- 其他 只要能請(qǐng)求到的,都能獲取 。
解析方式
- 直接處理
- json解析
- 正則表達(dá)式
- BeautifulSoup
- PyQuery
- XPath
2. 數(shù)據(jù)清洗
數(shù)據(jù)得到手,我們就需要對(duì)我們爬取的數(shù)據(jù)進(jìn)行清洗工作,為之后的數(shù)據(jù)分析做鋪墊,如果清洗的不到位勢(shì)必會(huì)對(duì)之后的數(shù)據(jù)分析造成影響。 下文將從數(shù)據(jù)格式統(tǒng)一、空值處理。
推薦好課:Python3進(jìn)階:數(shù)據(jù)分析及可視化
格式統(tǒng)一
去掉數(shù)據(jù)的空格中,在用爬蟲(chóng)進(jìn)行數(shù)據(jù)爬取時(shí)用 strip() 對(duì)爬取的字符串進(jìn)行處理,將中文數(shù)據(jù)轉(zhuǎn)換為阿拉伯?dāng)?shù)字。
例如1.7萬(wàn)變成17000,代碼如下:
def get_int(s):
if s[-1]=="萬(wàn)":
s=s[0:-1]
s=int(float(s)*10000)
else:
s=int(s)
return s
運(yùn)行結(jié)果如下
if __name__ == '__main__':
s="1.2萬(wàn)"
price = get_int(s)
print(price)#12000
空值處理
用爬蟲(chóng)對(duì)數(shù)據(jù)爬取的時(shí)候,若爬取的值不存在會(huì)報(bào)錯(cuò),用異常處理語(yǔ)句 try{} except: pass (try 為爬取視頻信息的代碼),跳過(guò)不存在的視頻信息數(shù)據(jù)。
try:
html=requests.get(Link).text
doc=BeautifulSoup(html);
List=doc.find('div',{'class':'ops'}).findAll('span')
like=List[0].text.strip()#點(diǎn)贊
like=self.getint(like)
coin=List[1].text.strip()#投幣
coin=self.getint(coin)
collection=List[2].text.strip()#收藏
collection=self.getint(collection)
print('點(diǎn)贊',like)
print('投幣',coin)
print('收藏',collection)
# #將數(shù)據(jù) 拼合成字典
data={
'Title':Title,
'link':Link,
'Up':Up,
'Play':Play,
'Like':like,
'Coin':coin,
'Collection':collection,
}
# 存儲(chǔ)到csv文件
self.write_dictionary_to_csv(data,'blibli2.csv')
pass
except:
pass
3.數(shù)據(jù)分析及可視化
表格參數(shù)信息如圖
對(duì)視頻排放量進(jìn)行分析
對(duì) B 站熱門(mén)播放量進(jìn)行分析,對(duì) 2020 年熱門(mén)視頻的播放量分為 4 個(gè)等級(jí) 一千萬(wàn)排放量以上為一個(gè)等級(jí) 五百萬(wàn)到一千萬(wàn)播放量為一個(gè)等級(jí) 五百萬(wàn)到一百萬(wàn)播放量為一個(gè)等級(jí) 一百萬(wàn)播放量以下為一個(gè)等級(jí)
l1=len(data[data['Play'] >= 10000000])
l2=len(data[(data['Play'] < 10000000) & (data['Play'] >=5000000)])
l3=len(data[(data['Play'] < 5000000) & (data['Play'] >=1000000)])
l4=len(data[data['Play'] < 1000000])
再數(shù)據(jù)通過(guò) matplotlib 庫(kù)進(jìn)行可視化。得到下圖。
plt.figure(figsize=(9,13)) #調(diào)節(jié)圖形大小
labels = ['大于一千萬(wàn)','一千萬(wàn)到五百萬(wàn)','五百萬(wàn)到一百萬(wàn)','小于一百萬(wàn)'] #定義標(biāo)簽
sizes = [l1, l2, l3, l4] #每塊值
colors = ['green', 'yellow', 'blue', 'red'] #每塊顏色定義
explode = (0,0,0,0) #將某一塊分割出來(lái),值越大分割出的間隙越大
# 中文亂碼和坐標(biāo)軸負(fù)號(hào)處理
plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams['axes.unicode_minus'] = False
patches,text1,text2 = plt.pie(sizes,
explode=explode,
labels=labels,
colors=colors,
autopct = '%3.2f%%', #數(shù)值保留固定小數(shù)位
shadow = False, #無(wú)陰影設(shè)置
startangle =90, #逆時(shí)針起始角度設(shè)置
pctdistance = 0.6) #數(shù)值距圓心半徑倍數(shù)距離
#patches餅圖的返回值,texts1餅圖外label的文本,texts2餅圖內(nèi)部的文本
# x,y軸刻度設(shè)置一致,保證餅圖為圓形
plt.axis('equal')
plt.title("B站熱門(mén)播放量分布圖")
plt.legend() # 右上角顯示
plt.show()
從圖中可以看出,在 B 站能上每周必看熱門(mén)推薦的視頻播放量大部分在五百萬(wàn)到一百萬(wàn)播放量,低于一百萬(wàn)播放量的視頻很難上每周必看熱門(mén)推薦,而一年中播放量達(dá)到于一千萬(wàn)的視頻也很少。 讓我們一起看看播放量排名前 10 的視頻是那些好看的視頻
data.nlargest(10,columns='Play')
再數(shù)據(jù)通過(guò) matplotlib 庫(kù)進(jìn)行可視化。得到下圖。
d.plot.bar(figsize = (10,8),x='Title',y='Play',title='Play top 10')
plt.xticks(rotation=60)#夾角旋轉(zhuǎn)60度
plt.show()
從圖中可以看出嗶哩嗶哩拜年祭最受歡迎且播放量遠(yuǎn)遠(yuǎn)高于其它視頻,說(shuō)明B站2020年拜年祭節(jié)目進(jìn)行的比較成功。
對(duì)作者進(jìn)行分析
通過(guò)數(shù)據(jù)分析看那個(gè)作者的作品上熱門(mén)次數(shù)最多,從而判斷那個(gè)作者在2020年中最受歡迎。 對(duì)作者進(jìn)行劃分,統(tǒng)計(jì)出現(xiàn)的次數(shù)
d2=data.loc[:,'Up'].value_counts()
d2=d2.head(10)
再數(shù)據(jù)通過(guò) matplotlib 庫(kù)進(jìn)行可視化。得到下圖。
d2.plot.bar(figsize = (10,8),title='UP top 10')
plt.show()
說(shuō)明 B 站上每周熱門(mén)次數(shù)最多的作者是涼風(fēng) Kaze,一年 52 周熱門(mén)推薦,一共出現(xiàn)了 48 次,幾乎每周熱門(mén)都有他的視頻出現(xiàn)。從數(shù)據(jù)來(lái)看,2020 年最受歡迎的作者是涼風(fēng) Kaze。
對(duì)視頻參數(shù)分析
對(duì)熱門(mén)視頻的點(diǎn)贊,投幣,收藏平均比例進(jìn)行分析
data['點(diǎn)贊比例'] = data['Like'] /data['Play']
data['投幣比例'] = data['Coin'] /data['Play']
data['收藏比例'] = data['Collection'] /data['Play']
d3=data.iloc[:,8:11]
d3=d3.mean()
再數(shù)據(jù)通過(guò) matplotlib 庫(kù)進(jìn)行可視化。得到下圖。
d3.plot.bar(figsize = (10,8),title='UP top 10')
plt.show()
2020年中點(diǎn)贊比例最高,達(dá)到大約9%。說(shuō)明在B站看視頻的人,平均10個(gè)人中才會(huì)有一個(gè)人點(diǎn)贊。而平均平均20個(gè)人中才會(huì)有一個(gè)人對(duì)視頻進(jìn)行投幣。
對(duì)標(biāo)題進(jìn)行分析
對(duì)標(biāo)題高頻次進(jìn)行提取,看那類標(biāo)題比較受歡迎 首先對(duì)所有標(biāo)題進(jìn)行遍歷,儲(chǔ)存在字符串s中
d4=data['Title']
s=''
for i in d4:
s=s+i
然后用詞云進(jìn)行可視化
標(biāo)題中帶有“朱一旦,半佛,羅翔”等作者名或“英雄聯(lián)盟,原神”等游戲熱門(mén)視頻比較多。