余豪士 匡芳君
摘 要:爬蟲(chóng)軟件是現(xiàn)今互聯(lián)網(wǎng)環(huán)境下,高效準(zhǔn)確地獲取數(shù)據(jù)的重要方式之一。針對(duì)傳統(tǒng)的初級(jí)爬蟲(chóng)技術(shù)易于被目標(biāo)網(wǎng)站攔截訪問(wèn)的問(wèn)題,簡(jiǎn)述爬蟲(chóng)的工作原理和方式,討論爬蟲(chóng)、反爬蟲(chóng)與反反爬蟲(chóng)之間的相互關(guān)系。分析應(yīng)對(duì)目標(biāo)網(wǎng)站的反反爬蟲(chóng)機(jī)制,包括偽裝用戶(hù)代理,設(shè)置IP地址代理、使用自動(dòng)化測(cè)試工具調(diào)用瀏覽器等技術(shù)要點(diǎn),并分析了基于Python語(yǔ)言中Requests庫(kù),構(gòu)建了對(duì)網(wǎng)頁(yè)的多種請(qǐng)求方式和數(shù)據(jù)獲取方法的解決方案。結(jié)合反反爬蟲(chóng)機(jī)制與數(shù)據(jù)分析技術(shù),以嗶哩嗶哩視頻網(wǎng)為案例,分析其網(wǎng)頁(yè)基本結(jié)構(gòu)與調(diào)用的應(yīng)用程序接口,使用Python與Requests庫(kù)抓取網(wǎng)站所有視頻的相關(guān)數(shù)據(jù)。數(shù)據(jù)清洗后分析播放量最高視頻的相關(guān)信息,并將結(jié)論以數(shù)據(jù)可視化的方式呈現(xiàn),實(shí)現(xiàn)對(duì)數(shù)據(jù)的獲取、挖掘與分析。
關(guān)鍵詞:網(wǎng)絡(luò)爬蟲(chóng); 反爬蟲(chóng); 反反爬蟲(chóng); 大數(shù)據(jù); 數(shù)據(jù)分析
Abstract: Crawler software is one of the most important ways to obtain data effectively and accurately in the current Internet environment. In view of the traditional crawler technology which is prone to be intercepted by target website, the paper explains how the crawler appears to work, discusses about the relationship between crawler, anti-crawler and anti-anti-crawler, and analyzes the mechanism of anti-anti-crawler for the target website, including fake user agents, setting IP proxy address, calling browser using automated testing tools. Furthermore, multiple requests and data acquisition methods for web pages are built based on Requests Library in Python language and its solution is analyzed. Combined with the mechanism of anti-anti crawler and data analysis technology, the paper takes the Bilibili website as a case, analyzing its basic structure, as well as its API called. On the one side, all relevant data of video on the Bilibili website is captured using Python and Requests Library and the related information of the video, in which the highest click rate is analyzed after data cleaning. On the other side, the conclusion is presented in the way of data visualization, and the data acquisition, mining and analysis are also realized.
Key words: Web crawler; anti-crawler; anti-anti-crawler technology; big data; data analysis
引言
大數(shù)據(jù)時(shí)代下的數(shù)據(jù)來(lái)源和獲取尤為重要[1],爬蟲(chóng)技術(shù)作為一項(xiàng)獲取數(shù)據(jù)的工具而被廣泛應(yīng)用。已超過(guò)60%的互聯(lián)網(wǎng)流量來(lái)自爬蟲(chóng)(Spider),各大搜索引擎門(mén)戶(hù)網(wǎng)站以及新聞網(wǎng)站的文章都與爬蟲(chóng)息息相關(guān)。爬蟲(chóng)技術(shù)已成為當(dāng)今的研究熱點(diǎn),目標(biāo)網(wǎng)站對(duì)爬蟲(chóng)軟件所做的各方面防范,給出了不同的攔截方式[2]。開(kāi)發(fā)者與開(kāi)發(fā)者之間通過(guò)爬蟲(chóng)、反爬蟲(chóng)、反反爬蟲(chóng)技術(shù)進(jìn)行較量,一方面開(kāi)發(fā)者想通過(guò)爬蟲(chóng)腳本獲取數(shù)據(jù),另一方面開(kāi)發(fā)者又想攔截爬蟲(chóng),防止爬蟲(chóng)腳本妨礙本網(wǎng)站的正常運(yùn)營(yíng),對(duì)正常用戶(hù)的訪問(wèn)造成了負(fù)面影響。
1 反反爬蟲(chóng)概述
1.1 反反爬蟲(chóng)技術(shù)
爬蟲(chóng)軟件是一種模擬瀏覽器的行為,是從指定網(wǎng)站抓取和保存網(wǎng)絡(luò)數(shù)據(jù)的應(yīng)用軟件。爬蟲(chóng)軟件提取出存在于網(wǎng)頁(yè)上的數(shù)據(jù),并以結(jié)構(gòu)化的方式存儲(chǔ)。主要活動(dòng)于計(jì)算機(jī)網(wǎng)絡(luò)通信模型中的傳輸層與應(yīng)用層。傳輸層使用TCP/IP協(xié)議與目標(biāo)Web服務(wù)器進(jìn)行數(shù)據(jù)傳輸;應(yīng)用層使用HTTP或HTTPS協(xié)議與目標(biāo)Web服務(wù)器通信[3]。
由于傳統(tǒng)的初級(jí)爬蟲(chóng)不使用任何隱藏偽裝手段,在對(duì)站點(diǎn)發(fā)送大量請(qǐng)求時(shí),會(huì)加重目標(biāo)Web服務(wù)器的負(fù)擔(dān),且容易被服務(wù)器偵測(cè)。在大中型網(wǎng)站中,開(kāi)發(fā)者會(huì)針對(duì)傳統(tǒng)的初級(jí)爬蟲(chóng)制定一系列的反爬機(jī)制,如針對(duì)爬蟲(chóng)軟件所處終端進(jìn)行IP限制;針對(duì)請(qǐng)求報(bào)文中Header屬性攔截爬蟲(chóng)軟件;通過(guò)分析網(wǎng)站流量和日志統(tǒng)計(jì)分析過(guò)濾爬蟲(chóng)。爬蟲(chóng)開(kāi)發(fā)者針對(duì)反爬蟲(chóng)機(jī)制,開(kāi)發(fā)了一套反反爬蟲(chóng)機(jī)制,在爬取數(shù)據(jù)的過(guò)程中防止被目標(biāo)站點(diǎn)攔截,開(kāi)發(fā)者需最大限度地將爬蟲(chóng)模擬成真人行為,獲取真實(shí)可靠的數(shù)據(jù)。初級(jí)爬蟲(chóng)、反爬蟲(chóng)、反反爬蟲(chóng)的關(guān)系如圖1所示。
1.2 反反爬蟲(chóng)策略
1.2.1 降低訪問(wèn)頻率
對(duì)目標(biāo)站點(diǎn)連續(xù)訪問(wèn)不同網(wǎng)頁(yè),如果不限制爬蟲(chóng)的請(qǐng)求頻率,爬蟲(chóng)的效率只會(huì)受到所處終端的處理能力和帶寬的限制,因此爬蟲(chóng)的訪問(wèn)頻率會(huì)非常高。通過(guò)增加線程的休眠時(shí)間,降低訪問(wèn)頻率,實(shí)現(xiàn)模仿人為瀏覽的行為。具體代碼如下:
import time
time.sleep(0.5)
1.2.2 偽裝用戶(hù)代理
用戶(hù)代理(User-Agent)是一種代表用戶(hù)行為的屬性,用于發(fā)送HTTP請(qǐng)求描述用戶(hù)系統(tǒng)和瀏覽器信息。站點(diǎn)服務(wù)器通過(guò)獲取報(bào)文中的User-Agent屬性,給不同操作系統(tǒng)與瀏覽器發(fā)送不同頁(yè)面。通常爬蟲(chóng)軟件在請(qǐng)求數(shù)據(jù)時(shí)不會(huì)攜帶此屬性字段,目標(biāo)站點(diǎn)也因此可偵測(cè)與進(jìn)行攔截。所以,爬蟲(chóng)腳本在請(qǐng)求時(shí)需在頭部加入類(lèi)似瀏覽器的User-Agent屬性[4]。例如:
headers = {'User-Agent':'Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'}
data = requests.get(url, headers=headers). text
1.2.3 IP代理
爬蟲(chóng)腳本在訪問(wèn)請(qǐng)求的過(guò)程中,TCP報(bào)文會(huì)攜帶客戶(hù)端的IP地址,站點(diǎn)服務(wù)器也因此可獲取到客戶(hù)端的IP地址。爬蟲(chóng)軟件訪問(wèn)頻率過(guò)高,站點(diǎn)服務(wù)器可對(duì)此IP地址進(jìn)行暫時(shí)性的封禁。開(kāi)發(fā)者在編寫(xiě)腳本時(shí)需要設(shè)置IP代理池。在多進(jìn)程下,多個(gè)進(jìn)程間使用不同的IP代理訪問(wèn)目標(biāo)網(wǎng)站,繞過(guò)站點(diǎn)服務(wù)器IP地址字段的檢測(cè),加快爬取數(shù)據(jù)的效率。例如:
proxies = {'http':'XX.XX.XX.XX:XXXX',
'https':'XX.XX.XX.XX:XXXX'}
data = requests.get(url, proxies=proxies). text
1.2.4 使用自動(dòng)化測(cè)試工具Selenium
Selenium是一個(gè)用于WEB開(kāi)發(fā)自動(dòng)化測(cè)試的軟件,其本身用于從用戶(hù)角度使用終端測(cè)試Web應(yīng)用,加載瀏覽器驅(qū)動(dòng)對(duì)網(wǎng)頁(yè)進(jìn)行操作。爬蟲(chóng)開(kāi)發(fā)者使用Selenium,并設(shè)置適應(yīng)的瀏覽器,例如Chome Driver或無(wú)頭瀏覽器PhantomJS,最大限度模擬真人行為。應(yīng)用代碼如下:
from selenium import webdriver
driver = webdriver.Chrome()
1.2.5 訪問(wèn)移動(dòng)端站點(diǎn)
網(wǎng)站根據(jù)終端瀏覽器的用戶(hù)代理相應(yīng)不同的頁(yè)面,其中終端分為移動(dòng)端和PC端。移動(dòng)端站點(diǎn)地址通常以WAP開(kāi)頭,且對(duì)爬蟲(chóng)軟件的限制不如PC端強(qiáng)。如果目標(biāo)站點(diǎn)有移動(dòng)端頁(yè)面且數(shù)據(jù)可抓性高,可以對(duì)移動(dòng)端頁(yè)面進(jìn)行抓取[5-6]。
2 基于Requests庫(kù)編寫(xiě)爬蟲(chóng)
Python中的第三方HTTP庫(kù)、Requests庫(kù)被爬蟲(chóng)開(kāi)發(fā)者廣泛應(yīng)用。Requests集成了定制請(qǐng)求頭、發(fā)送請(qǐng)求、傳遞URL參數(shù)、獲取相應(yīng)內(nèi)容等多種函數(shù)[7]。
2.1 發(fā)送請(qǐng)求
在發(fā)送請(qǐng)求上,Requests 集成了多種請(qǐng)求方式,例如最普遍的get和post請(qǐng)求,還有其他HTTP協(xié)議中的請(qǐng)求類(lèi)型。具體實(shí)現(xiàn)過(guò)程如下:
response = requests.get('https://httpbin.org/get')
response = requests.delete("http://httpbin.org/delete")
response = requests.options("http://httpbin.org/get")
2.2 傳遞 URL 參數(shù)
在瀏覽器地址輸入欄,輸入目標(biāo)網(wǎng)址的地址后,可輸入以鍵值對(duì)形成的參數(shù),最終形成一個(gè)完整的URL地址跳轉(zhuǎn)至目標(biāo)網(wǎng)頁(yè)。同理在Requests庫(kù)也有此功能,以字典的形式構(gòu)建。實(shí)現(xiàn)過(guò)程如下:
params = {'key1':'value1','key2': 'value2'}
response = requests.get('http://yhslib.com', params= params)
若要查看構(gòu)建后的完整地址,也可輸出查看。
2.3 定制請(qǐng)求頭
HTTP請(qǐng)求頭,Requests庫(kù)也給出了定制方式,以字典的形式構(gòu)建。實(shí)現(xiàn)過(guò)程如下:
headers = {'content-type': 'application/json'}
response = requests.get('http://yhslib.com', headers=headers)
2.4 獲取相應(yīng)內(nèi)容
通常所需的數(shù)據(jù)會(huì)顯示在網(wǎng)頁(yè)上,這也說(shuō)明數(shù)據(jù)包含在HTML或者JavaScript等文本類(lèi)型的文件中,通過(guò)獲取其文本信息經(jīng)過(guò)篩選即可獲得數(shù)據(jù)。Requests庫(kù)中可以通過(guò)獲取text獲得其文本:
r = requests.get('http://httpbin.org/get')
print(r.text)
有些情況下,所需數(shù)據(jù)以二進(jìn)制的文件存在,例如圖片、音頻、視頻等。在Requests中可通過(guò)獲得二進(jìn)制數(shù)據(jù),通過(guò)解碼和編碼得到最終數(shù)據(jù)文件。
JSON數(shù)據(jù)在數(shù)據(jù)交換和API接口領(lǐng)域中廣泛應(yīng)用。Requests中,對(duì)JSON類(lèi)型數(shù)據(jù)有獨(dú)立的獲取方式:
r = requests.get('https://XXX.XXX')
print(r.json())
3 案例分析
嗶哩嗶哩視頻網(wǎng)是中國(guó)的彈幕視頻分享網(wǎng)站,此網(wǎng)站的特色是懸浮在視頻上方實(shí)時(shí)地評(píng)論社交功能[8]。嗶哩嗶哩網(wǎng)主打動(dòng)漫視頻,吸引了大量年輕用戶(hù),具有音樂(lè)、舞蹈、科技、生活等板塊。據(jù)統(tǒng)計(jì),此網(wǎng)站注冊(cè)用戶(hù)已超過(guò)1.5億,其中24歲以下用戶(hù)占總用戶(hù)數(shù)的75%,每日視頻播放量已超過(guò)1億。分析網(wǎng)站中各個(gè)視頻的播放次數(shù)等關(guān)鍵數(shù)據(jù),得出用戶(hù)對(duì)此網(wǎng)站視頻的喜好。
3.1 分析網(wǎng)頁(yè)
打開(kāi)嗶哩嗶哩彈幕網(wǎng)中任意視頻詳情頁(yè),分析HTML代碼[9],可以發(fā)現(xiàn)每一個(gè)視頻頁(yè)中都有其相應(yīng)的播放量,用戶(hù)發(fā)送的彈幕數(shù)、捐贈(zèng)投幣數(shù)和收藏?cái)?shù)等關(guān)鍵數(shù)據(jù),如圖2所示。檢查其元素屬性和網(wǎng)頁(yè)元數(shù)據(jù)可以發(fā)現(xiàn),各個(gè)數(shù)值并非存在于網(wǎng)頁(yè)源碼中,而是通過(guò)AJAX[10]方式進(jìn)行異步交互[11]最終顯示在頁(yè)面中,因此需要從加載資源尋找。
3.2 獲取數(shù)據(jù)與分析接口
進(jìn)入調(diào)試模式,點(diǎn)擊Network選項(xiàng),可以搜索到相關(guān)API接口[12]。API接口分析如圖3所示,得到請(qǐng)求頭部信息,信息包括目標(biāo)地址(GET)、主機(jī)域名(Host)、用戶(hù)代理(User-Agent)、上一級(jí)網(wǎng)頁(yè)(Referer)、Cookie信息(Cookie)等信息。通過(guò)Get方式傳遞參數(shù),其中包含視頻編號(hào)(aid)。在編寫(xiě)爬蟲(chóng)腳本時(shí),需要偽造請(qǐng)求頭部信息,防止被站點(diǎn)攔截。
得到的數(shù)據(jù)包以JSON類(lèi)型返回,如圖4所示。數(shù)據(jù)包包括HTTP狀態(tài)碼(code)、數(shù)據(jù)屬性(data)、信息屬性(message)與TTL屬性。數(shù)據(jù)屬性中不僅包括上述中提到的播放量(view)、彈幕數(shù)(danmaku)、捐贈(zèng)投幣數(shù)(coin)和收藏?cái)?shù)(favorite),還包括視頻編號(hào)(aid)、評(píng)論數(shù)(reply)、分享次數(shù)(share)。
3.3 編寫(xiě)爬蟲(chóng)腳本與保存數(shù)據(jù)
由于視頻編號(hào)是一個(gè)隨機(jī)數(shù),所以需要從1開(kāi)始循環(huán)到視頻編號(hào)的最大值,且單次設(shè)置的最大值不宜過(guò)大,否則會(huì)導(dǎo)致內(nèi)存溢出[13]。
urls = ["https:// api.bilibili.com/x/web-interface/archive/stataid={} ".format(i) for i in range(100000)]
頭部請(qǐng)求只需包含用戶(hù)代理,連接狀態(tài)、主機(jī)地址等,其它信息可不攜帶[14]。
headers = {'User-Agent':'Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML,likeGecko)\\Chrome/59.0.3071.115 Safari/537.36', 'Host': 'api.bilibili.com'}
因此,請(qǐng)求數(shù)據(jù)和函數(shù)構(gòu)成如下:
data = requests.get(url, headers=headers, timeout=5).json()
最終的爬蟲(chóng)腳本偽代碼如下:
for url in urls:
data=get(url,herders=herders).json()
try:
download(data)
open bilibili.csv
write data
close bilibili.csv
獲取的數(shù)據(jù)以csv類(lèi)型文件保存。在爬取過(guò)程結(jié)束后,將數(shù)據(jù)保存至MySQL數(shù)據(jù)庫(kù)中,截至日前共有7 600 000余條記錄。以視頻播放量為排序條件選取播放量最多的100個(gè)視頻編號(hào)。通過(guò)視頻編號(hào)瀏覽其具體視頻頁(yè),抓取所在第一級(jí)分類(lèi)和第二級(jí)分類(lèi)具體信息。目標(biāo)網(wǎng)站所屬分類(lèi)如圖5所示。
3.4 統(tǒng)計(jì)數(shù)據(jù)信息
經(jīng)過(guò)數(shù)據(jù)分析,根據(jù)第一級(jí)分類(lèi)匯總,在視頻播放量最多的100個(gè)視頻中,國(guó)內(nèi)外番劇共有64個(gè),鬼畜有16個(gè),音樂(lè)和舞蹈各有6個(gè)和3個(gè),動(dòng)畫(huà)有3個(gè),其它分類(lèi)共8個(gè),如圖6所示。
統(tǒng)計(jì)百分比中,國(guó)內(nèi)外番劇占比最大,共占比64%,鬼畜分類(lèi)視頻占比16%,音樂(lè)占6%,舞蹈、生活、動(dòng)畫(huà)各占3%,其它分類(lèi)共占5%。
從數(shù)據(jù)中可以發(fā)現(xiàn),嗶哩嗶哩彈幕網(wǎng)的用戶(hù)最喜歡看國(guó)內(nèi)外動(dòng)漫番劇,在番劇占比64%中,其中日本動(dòng)漫占比58%,國(guó)創(chuàng)動(dòng)漫占比6%。由于日本動(dòng)漫數(shù)量遠(yuǎn)大于國(guó)創(chuàng)動(dòng)漫,因此日本動(dòng)漫播放量占比最大。鬼畜視頻多數(shù)由用戶(hù)自行上傳,主要提供用戶(hù)歡樂(lè)和笑聲,最受喜愛(ài)的視頻中占據(jù)第二位。嗶哩嗶哩彈幕網(wǎng)的用戶(hù)也喜歡音樂(lè)和舞蹈,對(duì)生活和動(dòng)畫(huà)制作這一塊也有一定的興趣。由此統(tǒng)計(jì)得到的結(jié)論,可以對(duì)網(wǎng)站首頁(yè)的輪播板塊設(shè)計(jì)提供參考。首推動(dòng)漫視頻與鬼畜視頻,對(duì)音樂(lè)和舞蹈制定一定的推送量,對(duì)其它分類(lèi)的視頻分類(lèi)減少推薦。
4 結(jié)束語(yǔ)
本文針對(duì)初級(jí)爬蟲(chóng)獲取網(wǎng)頁(yè)數(shù)據(jù)存在易于發(fā)現(xiàn)和速度慢等問(wèn)題,利用Python的Requests庫(kù)實(shí)現(xiàn)反反爬蟲(chóng)算法,并對(duì)其進(jìn)行了技術(shù)原理分析,最后通過(guò)相關(guān)案例描述了反反爬蟲(chóng)技術(shù)的簡(jiǎn)單應(yīng)用。文中實(shí)現(xiàn)的反反爬蟲(chóng)算法是基于Requests庫(kù)開(kāi)發(fā),具有速度快的優(yōu)點(diǎn)。但由于獲取的數(shù)據(jù)信息量不夠大,因此,下一步將對(duì)反反爬蟲(chóng)算法進(jìn)行改進(jìn)完善,并結(jié)合數(shù)據(jù)分析和人工智能開(kāi)展實(shí)際案例分析和應(yīng)用。
參考文獻(xiàn)
[1] 劉智慧,張泉靈. 大數(shù)據(jù)技術(shù)研究綜述[J]. 浙江大學(xué)學(xué)報(bào)(工學(xué)版),2014,48(6):957-972.
[2] 安子建. 基于Scrapy框架的網(wǎng)絡(luò)爬蟲(chóng)實(shí)現(xiàn)與數(shù)據(jù)抓取分析[D]. 長(zhǎng)春:吉林大學(xué),2017.
[3] 鄒科文,李達(dá),鄧婷敏,等. 網(wǎng)絡(luò)爬蟲(chóng)針對(duì)“反爬”網(wǎng)站的爬取策略研究[J]. 電腦知識(shí)與技術(shù),2016,12(7):61-63.
[4] 楊定中,趙剛,王泰. 網(wǎng)絡(luò)爬蟲(chóng)在Web信息搜索與數(shù)據(jù)挖掘中應(yīng)用[J]. 計(jì)算機(jī)工程與設(shè)計(jì),2009,30(24):5658-5662.
[5] 趙本本,殷旭東,王偉. 基于Scrapy的GitHub數(shù)據(jù)爬蟲(chóng)[J]. 電子技術(shù)與軟件工程, 2016(6):199-202.
[6] 焦文華. 基于Android的移動(dòng)互聯(lián)網(wǎng)應(yīng)用的研究和實(shí)現(xiàn)[D]. 北京:北京郵電大學(xué),2013.
[7] 謝克武. 大數(shù)據(jù)環(huán)境下基于python的網(wǎng)絡(luò)爬蟲(chóng)技術(shù)[J]. 電子制作,2017(9):44-45.
[8] KANG Shulong, ZHANG Chuang,LIN Zhiqing, et al. Complexity research of massively microblogging based on human behaviors[C] //2010 2nd International Workshop on Database Technology and Applications, DBT A2010 —Proceedings. Wuhan, China:IEEE Computer Society, 2010:1-4.
[9] BTTGER H, MLLER A, SCHWARTZBACH M I. Contracts for cooperation between Web service programmers and HTML designers[J].Journal of Web Engineering,2006,5(1):65-89.
[10]呂林濤,萬(wàn)經(jīng)華,周紅芳. 基于AJAX的Web無(wú)刷新頁(yè)面快速更新數(shù)據(jù)方法[J]. 計(jì)算機(jī)應(yīng)用研究,2006(11):199-200,223.
[11]熊文,熊淑華,孫旭,等. Ajax技術(shù)在Web2.0網(wǎng)站設(shè)計(jì)中的應(yīng)用研究[J]. 計(jì)算機(jī)技術(shù)與發(fā)展,2012,22(3):145-148.
[12]廉捷,周欣,曹偉,等. 新浪微博數(shù)據(jù)挖掘方案[J]. 清華大學(xué)學(xué)報(bào)(自然科學(xué)版), 2011,51(10):1300-1305.
[13]RAMALHO L. Fluent Python[M]. United States: O'Reilly Media Inc, 2015.
[14]JONES B, BEAZLEY D. Python Cookbook[M]. 3rd ed. United States: O'Reilly Media Inc, 2016.