余豪士 匡芳君
摘 要:爬蟲軟件是現今互聯網環境下,高效準確地獲取數據的重要方式之一。針對傳統的初級爬蟲技術易于被目標網站攔截訪問的問題,簡述爬蟲的工作原理和方式,討論爬蟲、反爬蟲與反反爬蟲之間的相互關系。分析應對目標網站的反反爬蟲機制,包括偽裝用戶代理,設置IP地址代理、使用自動化測試工具調用瀏覽器等技術要點,并分析了基于Python語言中Requests庫,構建了對網頁的多種請求方式和數據獲取方法的解決方案。結合反反爬蟲機制與數據分析技術,以嗶哩嗶哩視頻網為案例,分析其網頁基本結構與調用的應用程序接口,使用Python與Requests庫抓取網站所有視頻的相關數據。數據清洗后分析播放量最高視頻的相關信息,并將結論以數據可視化的方式呈現,實現對數據的獲取、挖掘與分析。
關鍵詞:網絡爬蟲; 反爬蟲; 反反爬蟲; 大數據; 數據分析
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
引言
大數據時代下的數據來源和獲取尤為重要[1],爬蟲技術作為一項獲取數據的工具而被廣泛應用。已超過60%的互聯網流量來自爬蟲(Spider),各大搜索引擎門戶網站以及新聞網站的文章都與爬蟲息息相關。爬蟲技術已成為當今的研究熱點,目標網站對爬蟲軟件所做的各方面防范,給出了不同的攔截方式[2]。開發者與開發者之間通過爬蟲、反爬蟲、反反爬蟲技術進行較量,一方面開發者想通過爬蟲腳本獲取數據,另一方面開發者又想攔截爬蟲,防止爬蟲腳本妨礙本網站的正常運營,對正常用戶的訪問造成了負面影響。
1 反反爬蟲概述
1.1 反反爬蟲技術
爬蟲軟件是一種模擬瀏覽器的行為,是從指定網站抓取和保存網絡數據的應用軟件。爬蟲軟件提取出存在于網頁上的數據,并以結構化的方式存儲。主要活動于計算機網絡通信模型中的傳輸層與應用層。傳輸層使用TCP/IP協議與目標Web服務器進行數據傳輸;應用層使用HTTP或HTTPS協議與目標Web服務器通信[3]。
由于傳統的初級爬蟲不使用任何隱藏偽裝手段,在對站點發送大量請求時,會加重目標Web服務器的負擔,且容易被服務器偵測。在大中型網站中,開發者會針對傳統的初級爬蟲制定一系列的反爬機制,如針對爬蟲軟件所處終端進行IP限制;針對請求報文中Header屬性攔截爬蟲軟件;通過分析網站流量和日志統計分析過濾爬蟲。爬蟲開發者針對反爬蟲機制,開發了一套反反爬蟲機制,在爬取數據的過程中防止被目標站點攔截,開發者需最大限度地將爬蟲模擬成真人行為,獲取真實可靠的數據。初級爬蟲、反爬蟲、反反爬蟲的關系如圖1所示。
1.2 反反爬蟲策略
1.2.1 降低訪問頻率
對目標站點連續訪問不同網頁,如果不限制爬蟲的請求頻率,爬蟲的效率只會受到所處終端的處理能力和帶寬的限制,因此爬蟲的訪問頻率會非常高。通過增加線程的休眠時間,降低訪問頻率,實現模仿人為瀏覽的行為。具體代碼如下:
import time
time.sleep(0.5)
1.2.2 偽裝用戶代理
用戶代理(User-Agent)是一種代表用戶行為的屬性,用于發送HTTP請求描述用戶系統和瀏覽器信息。站點服務器通過獲取報文中的User-Agent屬性,給不同操作系統與瀏覽器發送不同頁面。通常爬蟲軟件在請求數據時不會攜帶此屬性字段,目標站點也因此可偵測與進行攔截。所以,爬蟲腳本在請求時需在頭部加入類似瀏覽器的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代理
爬蟲腳本在訪問請求的過程中,TCP報文會攜帶客戶端的IP地址,站點服務器也因此可獲取到客戶端的IP地址。爬蟲軟件訪問頻率過高,站點服務器可對此IP地址進行暫時性的封禁。開發者在編寫腳本時需要設置IP代理池。在多進程下,多個進程間使用不同的IP代理訪問目標網站,繞過站點服務器IP地址字段的檢測,加快爬取數據的效率。例如:
proxies = {'http':'XX.XX.XX.XX:XXXX',
'https':'XX.XX.XX.XX:XXXX'}
data = requests.get(url, proxies=proxies). text
1.2.4 使用自動化測試工具Selenium
Selenium是一個用于WEB開發自動化測試的軟件,其本身用于從用戶角度使用終端測試Web應用,加載瀏覽器驅動對網頁進行操作。爬蟲開發者使用Selenium,并設置適應的瀏覽器,例如Chome Driver或無頭瀏覽器PhantomJS,最大限度模擬真人行為。應用代碼如下:
from selenium import webdriver
driver = webdriver.Chrome()
1.2.5 訪問移動端站點
網站根據終端瀏覽器的用戶代理相應不同的頁面,其中終端分為移動端和PC端。移動端站點地址通常以WAP開頭,且對爬蟲軟件的限制不如PC端強。如果目標站點有移動端頁面且數據可抓性高,可以對移動端頁面進行抓取[5-6]。
2 基于Requests庫編寫爬蟲
Python中的第三方HTTP庫、Requests庫被爬蟲開發者廣泛應用。Requests集成了定制請求頭、發送請求、傳遞URL參數、獲取相應內容等多種函數[7]。
2.1 發送請求
在發送請求上,Requests 集成了多種請求方式,例如最普遍的get和post請求,還有其他HTTP協議中的請求類型。具體實現過程如下:
response = requests.get('https://httpbin.org/get')
response = requests.delete("http://httpbin.org/delete")
response = requests.options("http://httpbin.org/get")
2.2 傳遞 URL 參數
在瀏覽器地址輸入欄,輸入目標網址的地址后,可輸入以鍵值對形成的參數,最終形成一個完整的URL地址跳轉至目標網頁。同理在Requests庫也有此功能,以字典的形式構建。實現過程如下:
params = {'key1':'value1','key2': 'value2'}
response = requests.get('http://yhslib.com', params= params)
若要查看構建后的完整地址,也可輸出查看。
2.3 定制請求頭
HTTP請求頭,Requests庫也給出了定制方式,以字典的形式構建。實現過程如下:
headers = {'content-type': 'application/json'}
response = requests.get('http://yhslib.com', headers=headers)
2.4 獲取相應內容
通常所需的數據會顯示在網頁上,這也說明數據包含在HTML或者JavaScript等文本類型的文件中,通過獲取其文本信息經過篩選即可獲得數據。Requests庫中可以通過獲取text獲得其文本:
r = requests.get('http://httpbin.org/get')
print(r.text)
有些情況下,所需數據以二進制的文件存在,例如圖片、音頻、視頻等。在Requests中可通過獲得二進制數據,通過解碼和編碼得到最終數據文件。
JSON數據在數據交換和API接口領域中廣泛應用。Requests中,對JSON類型數據有獨立的獲取方式:
r = requests.get('https://XXX.XXX')
print(r.json())
3 案例分析
嗶哩嗶哩視頻網是中國的彈幕視頻分享網站,此網站的特色是懸浮在視頻上方實時地評論社交功能[8]。嗶哩嗶哩網主打動漫視頻,吸引了大量年輕用戶,具有音樂、舞蹈、科技、生活等板塊。據統計,此網站注冊用戶已超過1.5億,其中24歲以下用戶占總用戶數的75%,每日視頻播放量已超過1億。分析網站中各個視頻的播放次數等關鍵數據,得出用戶對此網站視頻的喜好。
3.1 分析網頁
打開嗶哩嗶哩彈幕網中任意視頻詳情頁,分析HTML代碼[9],可以發現每一個視頻頁中都有其相應的播放量,用戶發送的彈幕數、捐贈投幣數和收藏數等關鍵數據,如圖2所示。檢查其元素屬性和網頁元數據可以發現,各個數值并非存在于網頁源碼中,而是通過AJAX[10]方式進行異步交互[11]最終顯示在頁面中,因此需要從加載資源尋找。
3.2 獲取數據與分析接口
進入調試模式,點擊Network選項,可以搜索到相關API接口[12]。API接口分析如圖3所示,得到請求頭部信息,信息包括目標地址(GET)、主機域名(Host)、用戶代理(User-Agent)、上一級網頁(Referer)、Cookie信息(Cookie)等信息。通過Get方式傳遞參數,其中包含視頻編號(aid)。在編寫爬蟲腳本時,需要偽造請求頭部信息,防止被站點攔截。
得到的數據包以JSON類型返回,如圖4所示。數據包包括HTTP狀態碼(code)、數據屬性(data)、信息屬性(message)與TTL屬性。數據屬性中不僅包括上述中提到的播放量(view)、彈幕數(danmaku)、捐贈投幣數(coin)和收藏數(favorite),還包括視頻編號(aid)、評論數(reply)、分享次數(share)。
3.3 編寫爬蟲腳本與保存數據
由于視頻編號是一個隨機數,所以需要從1開始循環到視頻編號的最大值,且單次設置的最大值不宜過大,否則會導致內存溢出[13]。
urls = ["https:// api.bilibili.com/x/web-interface/archive/stataid={} ".format(i) for i in range(100000)]
頭部請求只需包含用戶代理,連接狀態、主機地址等,其它信息可不攜帶[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'}
因此,請求數據和函數構成如下:
data = requests.get(url, headers=headers, timeout=5).json()
最終的爬蟲腳本偽代碼如下:
for url in urls:
data=get(url,herders=herders).json()
try:
download(data)
open bilibili.csv
write data
close bilibili.csv
獲取的數據以csv類型文件保存。在爬取過程結束后,將數據保存至MySQL數據庫中,截至日前共有7 600 000余條記錄。以視頻播放量為排序條件選取播放量最多的100個視頻編號。通過視頻編號瀏覽其具體視頻頁,抓取所在第一級分類和第二級分類具體信息。目標網站所屬分類如圖5所示。
3.4 統計數據信息
經過數據分析,根據第一級分類匯總,在視頻播放量最多的100個視頻中,國內外番劇共有64個,鬼畜有16個,音樂和舞蹈各有6個和3個,動畫有3個,其它分類共8個,如圖6所示。
統計百分比中,國內外番劇占比最大,共占比64%,鬼畜分類視頻占比16%,音樂占6%,舞蹈、生活、動畫各占3%,其它分類共占5%。
從數據中可以發現,嗶哩嗶哩彈幕網的用戶最喜歡看國內外動漫番劇,在番劇占比64%中,其中日本動漫占比58%,國創動漫占比6%。由于日本動漫數量遠大于國創動漫,因此日本動漫播放量占比最大。鬼畜視頻多數由用戶自行上傳,主要提供用戶歡樂和笑聲,最受喜愛的視頻中占據第二位。嗶哩嗶哩彈幕網的用戶也喜歡音樂和舞蹈,對生活和動畫制作這一塊也有一定的興趣。由此統計得到的結論,可以對網站首頁的輪播板塊設計提供參考。首推動漫視頻與鬼畜視頻,對音樂和舞蹈制定一定的推送量,對其它分類的視頻分類減少推薦。
4 結束語
本文針對初級爬蟲獲取網頁數據存在易于發現和速度慢等問題,利用Python的Requests庫實現反反爬蟲算法,并對其進行了技術原理分析,最后通過相關案例描述了反反爬蟲技術的簡單應用。文中實現的反反爬蟲算法是基于Requests庫開發,具有速度快的優點。但由于獲取的數據信息量不夠大,因此,下一步將對反反爬蟲算法進行改進完善,并結合數據分析和人工智能開展實際案例分析和應用。
參考文獻
[1] 劉智慧,張泉靈. 大數據技術研究綜述[J]. 浙江大學學報(工學版),2014,48(6):957-972.
[2] 安子建. 基于Scrapy框架的網絡爬蟲實現與數據抓取分析[D]. 長春:吉林大學,2017.
[3] 鄒科文,李達,鄧婷敏,等. 網絡爬蟲針對“反爬”網站的爬取策略研究[J]. 電腦知識與技術,2016,12(7):61-63.
[4] 楊定中,趙剛,王泰. 網絡爬蟲在Web信息搜索與數據挖掘中應用[J]. 計算機工程與設計,2009,30(24):5658-5662.
[5] 趙本本,殷旭東,王偉. 基于Scrapy的GitHub數據爬蟲[J]. 電子技術與軟件工程, 2016(6):199-202.
[6] 焦文華. 基于Android的移動互聯網應用的研究和實現[D]. 北京:北京郵電大學,2013.
[7] 謝克武. 大數據環境下基于python的網絡爬蟲技術[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]呂林濤,萬經華,周紅芳. 基于AJAX的Web無刷新頁面快速更新數據方法[J]. 計算機應用研究,2006(11):199-200,223.
[11]熊文,熊淑華,孫旭,等. Ajax技術在Web2.0網站設計中的應用研究[J]. 計算機技術與發展,2012,22(3):145-148.
[12]廉捷,周欣,曹偉,等. 新浪微博數據挖掘方案[J]. 清華大學學報(自然科學版), 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.