東南大學(xué)信息科學(xué)與工程學(xué)院 羅 咪
新浪微博作為我國(guó)主流社交媒體,擁有海量數(shù)據(jù)。自2009年推出以來,新浪微博的使用人數(shù)急速上升,帶來的是信息量的劇增。每天,人們通過轉(zhuǎn)發(fā)、互粉、點(diǎn)贊等行為發(fā)表自己的喜惡看法,將個(gè)人觀點(diǎn)放大到社會(huì)空間。在如今這個(gè)大數(shù)據(jù)時(shí)代,社交網(wǎng)絡(luò)分析依賴于海量的數(shù)據(jù)來探索人類社會(huì)關(guān)系中的奧秘,而如何獲取這些數(shù)據(jù)至關(guān)重要。在此之前,國(guó)外的研究學(xué)者已經(jīng)對(duì)Twitter、You-Tube等社交平臺(tái)進(jìn)行了一系列的分析,其研究方法相對(duì)成熟。他們獲取數(shù)據(jù)的主要方法是通過網(wǎng)站官方提供的API接口。[1]在國(guó)內(nèi),由于新浪官方目前限制相關(guān)數(shù)據(jù)接口的使用,所以研究者要想獲取數(shù)據(jù),需另辟蹊徑。[2]
本文基于Python語言提出了一種無需借助官方API接口就能獲取用戶數(shù)據(jù)的方法---多線程爬蟲技術(shù)。該項(xiàng)技術(shù)與傳統(tǒng)的網(wǎng)絡(luò)爬蟲相比,主要有以下三點(diǎn)改進(jìn):首先,使用多線程爬蟲取代傳統(tǒng)的單線程爬蟲,提高了數(shù)據(jù)獲取速率;其次,針對(duì)微博的反爬蟲機(jī)制設(shè)計(jì)了四種突破策略;最后,成功實(shí)現(xiàn)了對(duì)于微博評(píng)論等動(dòng)態(tài)網(wǎng)頁的爬取。
目前,用python實(shí)現(xiàn)多線程爬蟲主要有兩種方法。一是自行設(shè)計(jì)多線程函數(shù),二是使用python的scrapy包來包裝線程對(duì)象。[3] 本爬蟲系統(tǒng)主要使用Scrapy框架編寫,Scrapy框架是一種引擎和下載器之間的框架,主要功能是處理Scrapy引擎與下載器之間的請(qǐng)求及響應(yīng)。其基本組件和工作原理如圖1所示。
在Scrapy架構(gòu)下,用戶需要編寫爬蟲部件spiders和數(shù)據(jù)處理部件item pipeline。
模擬登陸是爬蟲技術(shù)所要攻克的第一個(gè)難題。所謂模擬登陸,即讓計(jì)算機(jī)模仿人工操作,以達(dá)到欺騙服務(wù)器的目的。我們分別嘗試了以下四種策略,并比較了它們的優(yōu)劣性。
(1)手動(dòng)獲取 cookie 登陸:該方法較為簡(jiǎn)單,但是需要人為參與,自動(dòng)化程度低。
(2)post 方法登陸weibo.com:該方法難度較高,主要因?yàn)橐韵氯c(diǎn)。其一,網(wǎng)頁版微博上存在大量的廣告圖片,javascript代碼復(fù)雜,從而降低了后續(xù)工作中源碼分析的效率。[4]其二,官方分別使用了Base64 和 RSA 加密算法對(duì)用戶賬號(hào)和密碼進(jìn)行了加密。其三,第一次跳轉(zhuǎn)到的URL在使用正則表達(dá)式匹配后才能得到目標(biāo)主頁。
圖1 Scrapy多線程爬蟲框架原理圖
(3)post方法登陸weibo.cn:由于移動(dòng)端頁面相對(duì)簡(jiǎn)潔,網(wǎng)頁源碼較少,所以相對(duì)登陸網(wǎng)頁版更加簡(jiǎn)單,但也存在兩個(gè)難點(diǎn)。其一,登陸時(shí)會(huì)出現(xiàn)驗(yàn)證碼,本文采用的解決方法是下載到本地然后手動(dòng)輸入。其二,登陸 http://weibo.cn/ 后會(huì)有一個(gè)重定向,這時(shí)必須設(shè)定user-agent,否則post完成后會(huì)卡在跳轉(zhuǎn)頁面。
(4)利用自動(dòng)化測(cè)試工具Selenium: Selenium 是一個(gè)自動(dòng)化測(cè)試工具,相當(dāng)于一個(gè)沒有界面瀏覽器,可以完全模擬瀏覽器行為,所以利用它進(jìn)行模擬登陸非常方便。[5]
新浪微博與豆瓣、知乎等其他社交網(wǎng)站的區(qū)別在于:微博中很多網(wǎng)頁都是動(dòng)態(tài)的,爬取有一定的難度,所以需要特殊處理。主要有兩種爬動(dòng)態(tài)網(wǎng)站的策略可以選取。第一種方法是使用自動(dòng)化測(cè)試工具selenium進(jìn)行抓取,這主要是因?yàn)閏hrome driver可以渲染用javascript生成的網(wǎng)站。具體做法是先獲取網(wǎng)頁源碼,再使用 XPath路徑語言解析網(wǎng)頁。Selenium 抓取雖然簡(jiǎn)潔方便,但存在抓取速率低效,不穩(wěn)定的缺點(diǎn),所以還可以使用解析json數(shù)據(jù)的方法。下面分別講解微博評(píng)論和用戶粉絲列表數(shù)據(jù)的獲取辦法。
首先,抓包尋找到網(wǎng)站ajax請(qǐng)求的接口,接著找尋該的接口url地址規(guī)律。例如,我們抓包后發(fā)現(xiàn)ajax請(qǐng)求為:
經(jīng)過測(cè)試后,我們可以將該url接口簡(jiǎn)化為:
從簡(jiǎn)化后的url地址可以歸納出新浪微博評(píng)論的接口規(guī)律為:
下面,我們需要通過微博地址獲取這條微博獨(dú)一無二的id。經(jīng)過網(wǎng)頁源碼分析我們發(fā)現(xiàn),微博的id出現(xiàn)在網(wǎng)頁dom元素屬性的很多地方,而且都是以mid開頭,這樣就能根據(jù)網(wǎng)頁源碼正則匹配出這條微博的id。[6]最后只要改變url接口里的page參數(shù),獲取所有評(píng)論源碼,再使用xpath提取出所需的評(píng)論數(shù)據(jù)即可。
以查看劉亦菲粉絲列表為例,抓包后得到結(jié)果如圖2所示。
圖2 劉亦菲粉絲列表抓包結(jié)果
可以得出粉絲列表的url地址為:
其中,每個(gè)粉絲擁有不同的containerid參數(shù),而since_id從1到250都可以訪問,所以每次訪問這個(gè)url都可以返回含有20個(gè)粉絲信息的json數(shù)據(jù)。如圖3所示。
圖3 劉亦菲粉絲列表json數(shù)據(jù)返回結(jié)果
為了防止個(gè)人盜取微博數(shù)據(jù)用于非法用途,新浪微博官方對(duì)微博爬蟲采取抵制態(tài)度,并且他們的反爬蟲機(jī)制也在不斷完善。如果爬蟲請(qǐng)求過于頻繁,賬戶容易被封禁,降低了數(shù)據(jù)獲取的效率。本系統(tǒng)采用以下4個(gè)策略突破微博的反爬蟲機(jī)制:
(1) 動(dòng)態(tài)更改 user-agent:主要利用python的fake user agent包,讓每一次請(qǐng)求都偽造一個(gè)用戶代理,使服務(wù)器誤以為是來自不同瀏覽器的請(qǐng)求。從而降低爬蟲被發(fā)現(xiàn)的概率。
(2)動(dòng)態(tài)更改 IP:首先獲取一串可用的高速代理 IP 列表,然后在每一次請(qǐng)求時(shí)更改 IP 地址,讓服務(wù)器無法鎖定具體的訪問地址,以達(dá)到迷惑服務(wù)器的目的。
(3)控制爬取速率:若爬取速率過快,服務(wù)器容易檢測(cè)出異常,所以速率一般控制在 1.5-2s為宜。
(4)建立并維護(hù)cookie 池:由于新浪微博會(huì)針對(duì)一個(gè)賬戶進(jìn)行速率監(jiān)控,所以更穩(wěn)妥的方法是一次多獲取幾個(gè) cookie,每次請(qǐng)求隨機(jī)設(shè)定一個(gè) cookie。
本文設(shè)計(jì)的新浪微博爬蟲使用python語言實(shí)現(xiàn),并且可以根據(jù)實(shí)際需要更改爬取條件和爬取目標(biāo)。在傳統(tǒng)靜態(tài)網(wǎng)頁爬蟲的基礎(chǔ)上,探討了針對(duì)新浪微博網(wǎng)站需要解決的三大問題: 模擬登陸、動(dòng)態(tài)網(wǎng)頁信息抓取、反爬蟲機(jī)制,并給出了切實(shí)可行的解決方案。在動(dòng)態(tài)網(wǎng)頁抓取中,需要應(yīng)用自動(dòng)化測(cè)試工具Selenium來模仿真正用戶的操作,以及利用正則表達(dá)式來匹配數(shù)據(jù)。值得一提的是,最終得到的數(shù)據(jù)往往與所需要的信息有細(xì)微差別,需要經(jīng)過數(shù)據(jù)清洗才能進(jìn)入分析的流程。實(shí)踐證明,該爬蟲系統(tǒng)能夠?qū)崿F(xiàn)對(duì)微博數(shù)據(jù)高效穩(wěn)定的采集,并符合實(shí)時(shí)性性、健壯性和靈活性等性能指標(biāo)要求。
[1]Axel Bruns, Yuxian Eugene Liang. (2012). Tools and methods for capturing Twitter data during natural disasters. Peer-Reviewed Journal on the Internet, 17(4).Retrieved from:http://journals.uic.edu/ojs/index.php/fm/article/view/3937.
[2]吳劍蘭.基于Python的新浪微博爬蟲研究[J].無線互聯(lián)科技,2015(06):93-94.
[3]李俊麗.基于Linux的python多線程爬蟲程序設(shè)計(jì)[J].計(jì)算機(jī)與數(shù)字工程,2015,43(05):861-863+876.
[4]陳珂,藍(lán)鼎棟,柯文德,黎樹俊,鄧文天.基于Java的新浪微博爬蟲研究與實(shí)現(xiàn)[J].計(jì)算機(jī)技術(shù)與發(fā)展,2017,27(09):191-196.
[5]吳伶琳.基于Selenium的軟件自動(dòng)化測(cè)試的研究與應(yīng)用[J].計(jì)算機(jī)與現(xiàn)代化,2013(02):65-68.
[6]胡軍偉,秦奕青,張偉.正則表達(dá)式在Web信息抽取中的應(yīng)用[J].北京信息科技大學(xué)學(xué)報(bào)(自然科學(xué)版),2011,26(06):86-89.