胡海潮
(昆明理工大學(xué),云南 昆明 650000)
隨著網(wǎng)絡(luò)技術(shù)的快速發(fā)展,信息社會(huì)進(jìn)入大數(shù)據(jù)時(shí)代。其中,在線社交網(wǎng)絡(luò)(Online Social Network,OLSN)所產(chǎn)生的數(shù)據(jù)特征尤其明顯,其規(guī)模巨大,內(nèi)容豐富,影響范圍廣[1-2]。因此,對(duì)此類社交網(wǎng)絡(luò)數(shù)據(jù)的采集研究,分析人物特點(diǎn),獲得統(tǒng)計(jì)規(guī)律具有十分重要的研究意義。
但如何有效地提取出這些信息成為研發(fā)人員一個(gè)巨大的挑戰(zhàn)。其中,新浪微博作為中國最具影響力的社交網(wǎng)絡(luò)工具之一,所產(chǎn)生的數(shù)據(jù)有別于傳統(tǒng)的線下數(shù)據(jù),其數(shù)據(jù)規(guī)模非常大,其信息可以在網(wǎng)絡(luò)中無限擴(kuò)展,熱點(diǎn)信息存在爆炸性增長特性,這些特點(diǎn)使得通過人工自己來尋求答案不僅費(fèi)時(shí),而且特別費(fèi)力[3]。此外,雖然新浪提供了供開發(fā)者獲取數(shù)據(jù)的訪問編程接口(OpenAPI),但其對(duì)普通用戶具有權(quán)限,抓取頻率等都有嚴(yán)格的限制,且無法對(duì)微博內(nèi)容進(jìn)行搜索[4]。為此,本文提出了一款基于新浪微博的爬蟲程序設(shè)計(jì)方法。
本文以移動(dòng)端微博用戶為例,設(shè)計(jì)并提出了一款以人與人關(guān)系為連接的網(wǎng)絡(luò)爬蟲,可以模擬登錄并獲取相關(guān)人物名稱等信息,并將這些數(shù)據(jù)保存到本地,方便做進(jìn)一步的數(shù)據(jù)挖掘與分析。同時(shí),本文爬蟲還通過解析關(guān)鍵路徑以匹配,利用該匹配功能可以實(shí)現(xiàn)網(wǎng)頁指定路徑的數(shù)據(jù)提取,最后,通過廣度遍歷,逐層獲得人物之間的關(guān)系[5]。使用本文爬蟲程序,不僅穩(wěn)定性強(qiáng)、易操作,而且還能夠縮短數(shù)據(jù)分析人員的開發(fā)程序所需時(shí)間,使得他們可以將更多的精力放在數(shù)據(jù)分析上面。
網(wǎng)絡(luò)爬蟲,也被稱為網(wǎng)頁蜘蛛[6]。簡單地說,便是一個(gè)計(jì)算機(jī)程序,按照定義好的規(guī)則從互聯(lián)網(wǎng)上抓取網(wǎng)頁信息。網(wǎng)絡(luò)爬蟲這種技術(shù)不僅可以用來檢查站點(diǎn)中所有鏈接是否有效,還可被搜索引擎使用,將抓取到的網(wǎng)頁的關(guān)鍵數(shù)據(jù)保存到本地。其最基本的思路為:將一批鏈接設(shè)為種子,然后從這些鏈接中獲取更多的鏈接進(jìn)行下一輪抓取[7]。然而實(shí)際應(yīng)用中,由于互聯(lián)網(wǎng)數(shù)據(jù)繁多,不可能將網(wǎng)上全部數(shù)據(jù)抓取下來,我們往往抓取到一定數(shù)量后,會(huì)自動(dòng)終止程序。據(jù)了解,現(xiàn)今最好的搜索引擎,也無法爬取整個(gè)互聯(lián)網(wǎng)一半的網(wǎng)頁。
Python語言是在計(jì)算生態(tài)的大背景下誕生、發(fā)展和再生,是一種功能強(qiáng)大、語法簡潔清晰的開源編程語言,且?guī)缀跄軌蛟谀壳八械牟僮飨到y(tǒng)上運(yùn)行[8-9]。其中,Python3系列語言在Python2的基礎(chǔ)上,又做了進(jìn)一步優(yōu)化,能夠?qū)⑵渌幊陶Z言最優(yōu)秀的成果封裝起來,簡化功能實(shí)現(xiàn)的復(fù)雜度,使我們爬取數(shù)據(jù)更加簡便。Python語言非常強(qiáng)大,是高效率的完全面向?qū)ο蟮恼Z言,能有效而簡單地實(shí)現(xiàn)面向?qū)ο缶幊蹋涞谌焦δ軒旌芏?,使用也很方便。因此,本文利用Python3作為編程語言進(jìn)行相關(guān)數(shù)據(jù)內(nèi)容的爬取。
廣度遍歷是連通圖的一種遍歷策略。其基本思想是:從圖中某一頂點(diǎn)V0出發(fā),首先訪問該頂點(diǎn);隨后從V0出發(fā),訪問與V0直接相連接但未曾訪問的頂點(diǎn)W1,W2,…Wk;然后,依次從W1,W2,…Wk出發(fā),訪問與其直接連接但未曾訪問的頂點(diǎn);重復(fù)上述步驟直至所有頂點(diǎn)全被訪問。由于社區(qū)網(wǎng)絡(luò)用戶信息量大、耗時(shí)長等原因,實(shí)際運(yùn)行時(shí),我們很難將全部用戶信息獲取完,所以我們首先會(huì)定義運(yùn)行到多少層用戶自動(dòng)結(jié)束。與其相類似的還有深度遍歷,此處不再贅述。
模擬瀏覽器登錄有兩種實(shí)現(xiàn)方法:(1)直接運(yùn)用網(wǎng)站中的cookie登錄。(2)通過模擬提交表單登錄。
方法1直接使用cookie登錄,避免了因用戶頻繁輸入賬號(hào)和密碼造成的不便,可以安全地登錄進(jìn)微博中,又不泄露用戶的隱私,利于系統(tǒng)的分布式實(shí)現(xiàn),可以支持導(dǎo)入第三方的賬戶,但是由于cookie本身的限制,一般只有3~5天的使用期限。
而方法2較為繁瑣,需要提供用戶名和密碼,網(wǎng)頁對(duì)其限制性比較大,但可靠性高,且沒有時(shí)間限制[3]。具體操作步驟如下:(1)通過網(wǎng)址,得到Http頭部的Set—cookie值。(2)設(shè)置cookie值,post用戶名和密碼到登錄頁面。(3)保存返回的set—cookie值,以供方法1使用。(4)設(shè)置新的cookie值,再次訪問主頁,并處理 Location 跳轉(zhuǎn)。
方法1和2各有利弊,本項(xiàng)目由于抓取時(shí)間不長。所以直接使用方法1來模擬登錄,不僅方便快捷,而且更快實(shí)現(xiàn)獲取我們想要得到的數(shù)據(jù)。
模擬登錄成功后,首先根據(jù)用戶提供給我們的新浪微博賬號(hào)(無需密碼)進(jìn)入初始頁,由于我們需要爬取該賬號(hào)關(guān)注的人名稱,所以得先獲取該賬戶關(guān)注人的頁數(shù)。
步驟如下:(1)進(jìn)入使用者關(guān)注人的第一頁。(2)獲取該網(wǎng)頁的所有文本信息。(3)從文本信息中抽取出頁數(shù)信息。
關(guān)鍵代碼如下:
其中,第三步直接使用XPath表達(dá)式,逐級(jí)檢索,獲得最終關(guān)鍵數(shù)據(jù):關(guān)注人頁數(shù)。
獲取用戶名稱與獲取總頁數(shù)步驟類似,只是將第三步中提取關(guān)鍵路徑改為:user_name1 = selector1.xpath(‘/html/body/div[4]/div[1]/text()’) 即可。
此步為整個(gè)過程中較為關(guān)鍵一步,首先得通過鏈接,從第一頁開始獲取用戶關(guān)注人的姓名與URL。這類似2.2,依舊分為3步:進(jìn)入網(wǎng)址;下載HTML;抽取所需信息。
然而,由于我們需要將其寫為一個(gè)子函數(shù),且保存兩類數(shù)據(jù),所以,首先得初始化一個(gè)對(duì)象items,用以保存從非結(jié)構(gòu)性的數(shù)據(jù)源提取結(jié)構(gòu)性數(shù)據(jù);緊接著,我們按照抽取所需信息的“三步曲”,實(shí)現(xiàn)獲得當(dāng)前頁面用戶關(guān)注人的名稱與URL鏈接,隨后,我們將獲取到的數(shù)據(jù)保存到items中。由于用戶關(guān)注人不止一頁,而我們之前得到了關(guān)注人用戶的總頁數(shù),此時(shí)可以外加一個(gè)for循環(huán),逐頁訪問,獲取數(shù)據(jù);最后,我們只需要返回items即可。
在獲取到我們想要得到的數(shù)據(jù)后,由于本項(xiàng)目是分析人際關(guān)系,且由于新浪微博不存在“重名現(xiàn)象”,所以,我們只需將用戶名稱與其關(guān)注對(duì)象名稱保存即可,而Excel是較為方便存儲(chǔ)的工具,以此作為我們存儲(chǔ)信息的文件。
定義一個(gè)子函數(shù):excel_write(),傳入items與user_name數(shù)據(jù);隨后,創(chuàng)建Excel表格,定義其名稱;Excel表格首行寫入關(guān)鍵詞:UserName及其HisFollow;最終,定義一個(gè)指針index,逐行寫入數(shù)據(jù)。
由于第一層的特殊性,隨后爬取的第二,三,四……層與其存在部分差異,緊接著,以獲取第二至三層數(shù)據(jù)為例,通過廣度遍歷獲得數(shù)據(jù)。
思路如下:(1)通過items,獲取第二層用戶ID。(2)獲取第二層用戶關(guān)注人的總頁面。(3)獲取用戶本身名稱。(4)獲取用戶關(guān)注對(duì)象所有名稱及其URL。(5)寫入Excel中。
可以看出來,大體上與2.1~2.4過程類似,只是將2.1的模擬登錄改為從items中提取用戶ID來;另外,第3步,由于items中其實(shí)已經(jīng)存在第二層用戶名稱,所以第3步可以直接刪除,第一步中直接提取用戶名稱即可。
其獲得部分?jǐn)?shù)據(jù)如圖1所示。
第2節(jié)已經(jīng)完成了程序所需爬取下來的信息,但在運(yùn)行過程當(dāng)中,會(huì)出現(xiàn)各種各樣的問題,本節(jié)是在第2節(jié)的基礎(chǔ)上,對(duì)程序進(jìn)行了改進(jìn),提升程序的穩(wěn)定性、實(shí)用性,以及優(yōu)化程序,使其更為簡單合理。
對(duì)一個(gè)網(wǎng)站訪問過于頻繁,往往就會(huì)被反爬蟲措施所識(shí)別和攔截[10],所以,當(dāng)我們?cè)L問網(wǎng)站以及下載網(wǎng)站信息時(shí),往往會(huì)設(shè)置延時(shí),其中,最簡單的是引入sleep庫,在需要延時(shí)訪問或下載信息前加上sleep()即可;其中,括號(hào)內(nèi)填入需要延時(shí)的時(shí)間。
另外,Scrapy也提供了一種比較智能的方法來解決限速問題,即通過自動(dòng)限速擴(kuò)展,該擴(kuò)展能根據(jù)Scrapy服務(wù)器及爬取的網(wǎng)站的負(fù)載自動(dòng)限制爬取速度。
由于本程序運(yùn)行時(shí)間較長,當(dāng)我們需要了解程序運(yùn)行到哪一步時(shí),不可能中斷程序,了解進(jìn)程。所以,在編寫程序時(shí),在相應(yīng)步驟結(jié)束后,加上 print(“… ”) 即可,此優(yōu)化較為簡單,不再敘述。
另外,由于網(wǎng)頁的特殊性,程序可能會(huì)出現(xiàn)未知錯(cuò)誤,而造成中途不再下載數(shù)據(jù),浪費(fèi)時(shí)間。所以為了提升程序的健壯性,我們?cè)诔绦蛑锌赡軙?huì)出現(xiàn)錯(cuò)誤的地方加上try…catch…語句,如在獲取用戶名稱時(shí):
圖1 部分爬取數(shù)據(jù)展示
可以方便地了解在爬取過程中,在哪一步出現(xiàn)了差錯(cuò),并自動(dòng)跳過,而不會(huì)造成浪費(fèi)接下來爬取信息的時(shí)間。
當(dāng)我們想要獲取關(guān)注人信息時(shí),在搜索每名用戶時(shí),均要首先獲取其關(guān)注人頁數(shù)信息,不僅費(fèi)時(shí),而且也容易出現(xiàn)錯(cuò)誤,此處,我們提出一種新的翻頁功能實(shí)現(xiàn)的方法,其本質(zhì)就是通過構(gòu)造Request并提交Scrapy引擎的過程。
關(guān)鍵步驟是當(dāng)我們?cè)讷@取完第n頁信息完畢之后,首先抽取下一頁的鏈接,如果存在,便訪問下一頁,爬取信息,否則跳過。
運(yùn)用Python3豐富的庫資源以及快速開發(fā)的特點(diǎn),本文設(shè)計(jì)并實(shí)現(xiàn)了基于新浪微博數(shù)據(jù)上的社區(qū)網(wǎng)絡(luò)爬蟲程序,為研究社會(huì)中人物關(guān)系者們提供了較為簡單方便的新浪微博數(shù)據(jù)獲取程序。該程序使用者僅需提供新浪微博賬號(hào)即可利用爬蟲抓取新浪微博中的人物關(guān)聯(lián)信息,解決了傳統(tǒng)爬蟲登錄、翻頁等問題;實(shí)驗(yàn)結(jié)果表明:該爬蟲具有良好的性能,穩(wěn)定性強(qiáng),可以投入到日常使用當(dāng)中,并且有利于對(duì)微博的后續(xù)挖掘研究。
[參考文獻(xiàn)]
[1]楊文剛,韓海濤.大數(shù)據(jù)背景下基于主題網(wǎng)絡(luò)爬蟲的檔案信息采集[J].蘭臺(tái)世界,2015(20):20-21.
[2]鄭楷堅(jiān),沙瀛.面向主題的社交網(wǎng)絡(luò)采集技術(shù)[J].計(jì)算機(jī)系統(tǒng)應(yīng)用,2016(10):173-179.
[3]郭濤,黃銘鈞.社區(qū)網(wǎng)絡(luò)爬蟲的設(shè)計(jì)與實(shí)現(xiàn)[J].智能計(jì)算機(jī)與應(yīng)用,2012(4):65-67.
[4]劉艷平,俞海英,戎沁.Python模擬登錄網(wǎng)站并抓取網(wǎng)頁的方法[J].微型計(jì)算機(jī)應(yīng)用,2015(1):58-60.
[5]魏春蓉,張宇霖.基于新浪微博的社交網(wǎng)絡(luò)用戶關(guān)系分析[J].中華文化論壇,2016(9):156-161.
[6]陳琳,任芳.基于Python的新浪微博數(shù)據(jù)爬蟲程序設(shè)計(jì)[J].技術(shù)應(yīng)用,2016(9):97-99.
[7]羅剛.自己動(dòng)手寫網(wǎng)絡(luò)爬蟲[M].北京:清華大學(xué)出版社,2016.
[8]馬俊哲.面向微博用戶行為數(shù)據(jù)挖掘的爬蟲系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[D].武漢:華中科技大學(xué),2016.
[9]范傳輝.Python爬蟲開發(fā)與項(xiàng)目實(shí)戰(zhàn)[M].北京:機(jī)械工業(yè)出版社,2017.
[10]陳利婷.大數(shù)據(jù)時(shí)代的反爬蟲技術(shù)[J].電腦與信息技術(shù),2016(6):60-61.