杜翔, 蔡燕, 蘭小機(jī)
(江西理工大學(xué),a.西校區(qū)管委會;b.建筑與測繪工程學(xué)院,江西 贛州 341000)
智能手機(jī)的普及、web2.0技術(shù)的日益成熟以及移動網(wǎng)絡(luò)的迅速發(fā)展,使得社交媒體軟件迅速發(fā)展和被使用.據(jù)統(tǒng)計,國內(nèi)最大的微博平臺——新浪微博截至2017年9月,活躍用戶就達(dá)到了3.76億[1].用戶借助微博平臺,在網(wǎng)絡(luò)上留下各種“足跡”,包括評論、圖片、視頻、地理位置和個人信息等,尤其在外出游玩過程中,用戶到達(dá)旅游目的地之后傾向于通過微博隨時隨地發(fā)布心情和照片等,這些數(shù)據(jù)經(jīng)過長時間的積累便會形成大規(guī)模的數(shù)據(jù)量.由于數(shù)據(jù)都是用戶根據(jù)自己當(dāng)時的感受、所想而產(chǎn)生的,他人干預(yù)的因素較小,因此數(shù)據(jù)能較為真實的反映出用戶當(dāng)時的狀態(tài),具有較高的挖掘價值.
周中華等[2]通過模擬登錄微博成功獲取了大量的微博文本,對用戶社交圖譜及感冒數(shù)據(jù)進(jìn)行了分析;陳琳等[3]通過爬蟲獲取了發(fā)布微博的時間與微博文本,分析與霧霾相關(guān)微博數(shù)量在不同時間尺度下的變化關(guān)系;A Tumasjan等[4]通過分析twitter上的十萬條信息的情感,準(zhǔn)確的反映了當(dāng)時的選舉結(jié)果;Burns等[5]通過追蹤2012年2月至2012年3月24日之間twitter的使用情況,表明社會媒體活動在國家級競選活動中的相對重要性;劉乙坐和張明旺等[6-7]等通過分析微博特點,提出了一套讓政府有關(guān)部門可以有力監(jiān)測和引導(dǎo)輿論的機(jī)制;易善君等[8]通過分析微博數(shù)據(jù)和空氣數(shù)據(jù),研究空氣質(zhì)量與居民情感之間的關(guān)系,得出空氣中對居民情感影響較大的為顆粒物質(zhì)與有刺激性氣味的氣體.關(guān)于微博爬蟲和微博數(shù)據(jù)的研究非常多,但是由于他們沒有獲取到發(fā)布微博的位置數(shù)據(jù),研究受到了局限,如果有發(fā)布微博位置數(shù)據(jù),就能分析輿論的傳播路徑,還能分析感冒、霧霾、情感等信息與地理位置之間的關(guān)系.所以文中提出一個基于Python的微博位置數(shù)據(jù)的獲取方法,來增加微博數(shù)據(jù)的維度,使微博數(shù)據(jù)的價值和可研究性提高.
新浪微博API[9]的功能十分強(qiáng)大且高效,用戶可以通過調(diào)用新浪API獲取海量的微博數(shù)據(jù).用戶只需在新浪微博開放平臺上注冊成為開發(fā)者后通過OAuth授權(quán)即可調(diào)用API開始獲取微博數(shù)據(jù).
雖然這種方法簡單、高效,但是新浪微博并沒有將所有的API調(diào)用權(quán)限交給開發(fā)者,而且還限制了API的調(diào)用頻率,如果想要高頻率的調(diào)用API需要和新浪進(jìn)入深度合作.
綜上所訴,這種方法雖然簡單、快捷,但作為普通用戶能獲取到的數(shù)據(jù)量不僅較少,而且因為API權(quán)限問題,普通用戶也不一定能獲取到想要的數(shù)據(jù),所以這個方法不是一個理想的微博位置數(shù)據(jù)獲取方法.
基于Python的網(wǎng)絡(luò)爬蟲技術(shù)[10-15]研究已經(jīng)十分成熟,能比較簡單的獲取特定的數(shù)據(jù).大部分采用的是多線程方法,而Python里的多線程是單cpu意義上的多線程,因此采集速度無法提升太多.本文提出的方法為并行化爬蟲,該方法包括五個部分:一是模擬登錄[11]部分,用于模擬登錄新浪微博,解決數(shù)據(jù)的訪問權(quán)限問題;二是URL管理部分,使用Redis維護(hù)未完成集合(New Set)和已完成集合(Old Set),避免重復(fù)爬取且能夠使程序并行化,提高數(shù)據(jù)的獲取效率;三是下載部分,用于下載服務(wù)器返回的html代碼;四是網(wǎng)頁解析部分,解析出htm l代碼中所包含的微博信息及用戶信息;五是輸出部分,將解析后得到的內(nèi)容輸出到數(shù)據(jù)庫中保存.
通過使用fiddler抓取m.weibo.com網(wǎng)站登錄的數(shù)據(jù)包可以發(fā)現(xiàn),賬號密碼都是明文POST到https://passport.weibo.cn/sso/login網(wǎng)頁,驗證成功后返回“retcode:2000000”的 json 數(shù)據(jù)(如圖 1 所示).明文傳遞使模擬登錄變得簡單.但是由于要爬取地理坐標(biāo)數(shù)據(jù),單單只是模擬登錄手機(jī)網(wǎng)頁版微博是不夠的,所以必須獲得一個可以訪問所有新浪網(wǎng)站的cookie.
自動模擬登錄具體流程如下:
1.使用Urllib2庫創(chuàng)建三個帶cookie的opener分別是 opener1、opener2、opener3;
2.輸入登錄新浪微博的用戶名和密碼;
3.使用opener1將用戶名、密碼和header信息POST到https://passport.weibo.cn/sso/login(稱之為URL1);
4.獲取返回信息中的weibo.com的ticket為ticket1,sina.com.cn 的 ticket為 ticket2;
5.使用opener2訪問https://passport.weibo.com/sso/crossdomain?entry=mweibo&action=login&p roj=1&ticket =ticket1&savestate =1&callback =jsonpcallback1(稱之為 URL2).
6.使用opener3訪問https://login.sina.com.cn/sso/crossdomain?entry=mweibo&action=login&proj=1&ticket=ticket2&savestate=1&callback=jsonpcallback(稱之為 URL3).
7.使用opener3訪問http://login.sina.com.cn/sso/login.php(稱之為URL4)并解析得到ticket和ssosavestate(如圖 2 所示).
8.使用opener2訪問http://passport.weibo.com/wbsso/login?ticket=ticket&ssosavestate=ssosavestate&callback=sinaSSOController.doCrossDomainCallBack&scriptId=ssoscript0&client=ssologin.js(v1.4.19)( 稱之為 URL5).
9.這樣就完成了整個的登錄過程,此時opener2中所帶的cookie可以訪問新浪各個域中的內(nèi)容.
自動模擬登錄流程圖如圖3所示.
圖2 opener3訪問http://login.sina.com.cn/sso/login.php返回的htm l
圖3 自動模擬登錄流程
新浪微博數(shù)據(jù)需要模擬登錄后才能訪問,所以本部分使用的是opener2對新浪URL進(jìn)行訪問.由于微博返回數(shù)據(jù)使用了GZIP壓縮,所以需要使用Python自帶的StringIO庫對內(nèi)容進(jìn)行解壓,解壓后可得到服務(wù)器返回的html代碼.下載流程圖如圖4所示.
文中使用Python的re庫中正則表達(dá)式來提取用戶基本信息,使用Python的BeautifulSoup庫將HTML解析為DOM對象來提取微博數(shù)據(jù).由于本文只獲取贛州、上海、南昌地區(qū)的微博數(shù)據(jù),故直接把用戶所在地區(qū)不是贛州、上海、南昌的微博數(shù)據(jù)直接過濾、丟棄.解析部分流程圖如圖5所示.
URL管理部分的主要功能是維護(hù)兩個隊列,分別是未完成集合(New Set)和已完成集合(Old Set).文中使用Redis作為隊列的存儲軟件,有以下兩個優(yōu)點:
圖4 下載流程
圖5 解析部分流程
第一,支持集合(SET).因為相同的頁面我們只需要爬取一次,通過使用集合(set)可以自動的為我們?nèi)ブ兀簿褪钦f,我們在頁面中解析到的URL只需要和已完成集合中的URL進(jìn)行匹配,如果該URL不在已完成集合中就可以往未完成集合中存儲,自動去重使得我們的未完成集合中的URL全為未爬取過的且沒有重復(fù)的URL.
第二,使用Redis可以使爬蟲并行化.各個節(jié)點只需將解析到的URL交給URL管理器處理,將未爬取的URL存放到未完成集合中,然后各個節(jié)點通過URL管理器從未完成集合中取出URL進(jìn)行數(shù)據(jù)爬取.URL管理部分流程圖如圖6、圖7所示.
圖6 存入URL流程
圖7 取出URL流程
將解析好的用戶信息及微博數(shù)據(jù)存儲到MongoDB,將解析到的URL信息傳遞給URL管理器管理.其中微博數(shù)據(jù)包括昵稱、用戶ID、用戶性別、用戶所在地區(qū)、用戶年齡、微博文本、微博文本發(fā)布時間、微博文本發(fā)布地點及坐標(biāo),在MongoDB 中 分 別 使 用 “name”、 “Id”、 “gender”、“addr”、“age”、“Text”、“date”、“pao_dl_address”和“Location”表示.
根據(jù)上述的5個部分,將其進(jìn)行整合得到微博爬蟲系統(tǒng)整體流程圖如圖8所示.
運行爬蟲主程序的計算機(jī)配置如表1所示.
運行Redis和MongoDB的計算機(jī)配置如表2所示.
圖8 微博爬蟲系統(tǒng)整體流程
表1 運行爬蟲主程序的計算機(jī)配置
表2 運行Redis和M ongoDB的計算機(jī)配置
本文爬蟲運行在表1所示的計算機(jī)中,爬蟲進(jìn)程數(shù)從1逐步增加至5,得到每小時微博數(shù)據(jù)采集速率變化曲線如圖9所示.
圖9 微博數(shù)據(jù)采集速率與爬蟲進(jìn)程數(shù)的關(guān)系曲線
根據(jù)圖9可以發(fā)現(xiàn):①隨著進(jìn)程數(shù)的增加,微博數(shù)據(jù)采集速率逐漸增加;②當(dāng)爬蟲進(jìn)程數(shù)小于等于3時,采集速率基本呈一條直線上升,有些許波動,但是不大,當(dāng)進(jìn)程數(shù)大于3時,采集速率增加幅度明顯下降,這是由于此時計算機(jī)性能開始限制爬蟲的工作效率.
文中通過同時開啟3個爬蟲進(jìn)程爬取微博數(shù)據(jù),爬取界面如圖10所示.
經(jīng)過10天的爬取,得到微博數(shù)據(jù)2152122條,其中贛州區(qū)域313450條,上海區(qū)域1401914條,南昌區(qū)域436758條.
圖10 爬蟲爬取微博的界面
微博數(shù)據(jù)在MongoDB中存儲的形式如圖11所示.
通過文中提出的爬蟲能夠較好的爬取微博數(shù)據(jù),采集速率也可根據(jù)情況進(jìn)行調(diào)節(jié),在不超過計算機(jī)性能的情況下,爬蟲進(jìn)程數(shù)越多,速率越快,如果達(dá)到單臺計算機(jī)性能極限時,仍需提高數(shù)據(jù)采集效率,只需增加計算機(jī),并在其上運行爬蟲進(jìn)程即可.需要說明的是,本文爬取的微博文本是帶地理坐標(biāo)的,該類微博相比于普通微博數(shù)量要少的多,所以有相當(dāng)一部分不帶地理坐標(biāo)的微博數(shù)據(jù)被舍棄,使得數(shù)據(jù)的獲取效率顯得較低.
通過使用Python提供的豐富的庫,本文提出了基于Python的新浪微博位置數(shù)的獲取方法,并根據(jù)該方法實現(xiàn)了一個爬蟲程序.該程序只需要使用者輸入微博賬號密碼,就能獲得可以訪問所有新浪網(wǎng)站的cookie,能夠抓取特定區(qū)域中的帶地理坐標(biāo)微博數(shù)據(jù),并自動存儲在MongoDB數(shù)據(jù)庫中.帶地理坐標(biāo)的微博數(shù)據(jù),不僅可以研究其文本內(nèi)容,如情感分析、輿情分析等等,更可以結(jié)合地理位置進(jìn)行分析,如居民活動空間研究[16]等等,提供了更多的微博數(shù)據(jù)的應(yīng)用[17].
圖11 微博數(shù)據(jù)存儲在M ongoDB中的存儲形式