陳 珂,藍鼎棟,柯文德,黎樹俊,鄧文天
(廣東石油化工學院 計算機與電子信息學院,廣東 茂名 525000)
基于Java的新浪微博爬蟲研究與實現
陳 珂,藍鼎棟,柯文德,黎樹俊,鄧文天
(廣東石油化工學院 計算機與電子信息學院,廣東 茂名 525000)
為了高效獲取更多的微博數據,針對調用微博API和網頁版(com版)等傳統微博爬蟲在數據采集中所存在的問題,設計開發了一個基于Java的采集新浪微博Weibo.cn站點的網絡爬蟲系統。該系統通過廣度遍歷結合組拼URL的方式采集網頁源碼,使網頁源碼更加簡潔,純凈度更高,降低了網絡傳輸壓力并減少了HTML源碼解析時間。主要實現了微博模擬登陸、微博網頁爬取、微博頁面數據提取和任務調度控制,并對爬取數據進行了分析,在爬蟲中添加了主題微博篩選功能。為驗證該系統的有效性和可行性,與其他傳統方法進行了分析對比。實驗驗結果表明,所提出的系統爬取效率更高,實現代碼更簡便。
新浪微博;網絡爬蟲;Java;數據挖掘
隨著計算機與網絡技術的快速發展,社交網絡平臺是人們喜愛的網絡社交方式。目前廣為流行的微博系統,對人們的生活方式影響巨大。伴隨著微博使用人數的急劇上升,產生了巨大的數據量,由此可以從中挖掘出大量的有用信息,而基于微博的數據挖掘研究已成為當今社會科學和計算機科學研究的重點。微博(Weibo)是一種通過關注機制分享簡短實時信息的廣播式的社交網絡平臺,也是一個基于用戶關系的信息分享、傳播以及獲取的平臺[1]。用戶可以通過WEB、WAP等各種客戶端組建個人社區,以140字(包括標點符號)的文字更新信息,并實現即時分享。微博的關注機制分為可單向、可雙向兩種。微博作為一種分享和交流平臺,其更注重時效性和隨意性。
比較知名的微博系統是2006年推出的Twitter,人們對它進行了一系列的研究與數據分析,特別是利用數據挖掘技術從中獲取了大量有用信息。2009年新浪微博系統推出,它提供的微博API的使用限制很多,最大的問題是調用次數少,測試授權單個IP每小時只能請求1 000次,而且每次調用時都是獲取一個用戶的某個數據集,雖然利于獲取單個用戶的大量數據集,但不利于廣度抓取全網用戶的最新信息。當然傳統爬蟲有廣度爬取頁面的能力,但是微博需要用戶進行登錄驗證才有權限訪問大量的微博頁面,并且傳統爬蟲獲取新URL的方式一般是通過HTML源碼中提取[2-4]。所構建的微博爬蟲是通過用戶ID獲取,可以進行URL組拼,數據是動態加載的,要判斷是否存在下一頁。所以,為了更快速獲取大量更有用的微博數據,必須編寫特定需求的微博網絡爬蟲系統。目前基于weibo.cn數據采集方面的研究較少,針對調用微博API、傳統爬蟲、網頁版(com版)微博爬蟲存在的問題,設計開發了一個基于Java新浪微博weibo.cn站點的網絡爬蟲系統[5-6]。
1.1微博爬蟲的主要結構與流程
所用的開源工具包或組件有:org.seleniumhq.selenium-java-2.45.0組件(內含htmlunit-2.15.jar,java頁面分析工具包),org.apache.httpcomponents-httpclient-4.3.5(內含httpclient-4.3.5.jar,支持HTTP協議的客戶端編程工具包),org.htmlparser-2.1(內含htmlparser-2.1.jar,html解析工具包);輔助工具有瀏覽器Firefox和它的網站調試工具Firebug。
微博爬蟲主要功能流程(見圖1)說明如下:

圖1 微博爬蟲主要功能流程圖
(1)通過htmlunit模擬登陸weibo.cn站點,登陸成功后會獲取到名為gsid_CTandWM的cookie字段;
(2)把所有返回的cookie字段存入httpclient的http代理(相當于一個瀏覽器);
(3)從種子URL開始爬取,從微博服務器中請求URL對應的html源碼;
(4)交給html源碼解釋程序模塊,調用htmlparser里面的功能函數和正則表達式進行URL和微博數據的提取與入庫。
在這個過程中,要維護一個待爬隊列和一個近期已爬取過的URL的已爬隊列,新爬取的URL如果都不在這兩個隊列中,就把它存進待爬隊列,已爬取過的URL存放進已爬隊列,并且根據存放時間決定是否釋放掉[7-8]。
1.2微博模擬登陸
現在微博的無限制訪問需要用戶進行驗證登錄,有兩種新浪微博服務器可供選擇,一種是爬取weibo.cn服務器(以下簡稱cn版微博),另一種是爬取weibo.com服務器(以下簡稱com版微博)。cn版微博的頁面相對com版的頁面更加簡潔,網頁源碼更少,登陸賬號密碼都不加密,而且所需信息全面。電腦版模擬登陸需要對用戶名和用戶密碼進行加密傳輸,而且JavaScript和廣告圖代碼很多,會降低HTML源碼分析效率和增加網絡傳輸壓力[9]。因此,主要采用手機版模擬登陸方式和抓取手機版微博頁面。
1.2.1 com版微博的模擬登陸
通過Firefox和Firebug分析了微博網頁版登陸方式,其主要登陸步驟為:
(1)瀏覽器向微博服務器發送一個Get請求,服務器返回名為servertime數值和名為nonce的隨機生成的字符串,每次登陸前隨機生成傳回給客戶端加密用戶密碼;
(2)根據步驟1返回的字段值,使用BASE64算法加密賬號名,用RSA算法對servertime加上nonce再加上用戶密碼這三個值組成的字符串進行加密,得到加密后的用戶密碼,向服務器發送包含加密過的用戶名和用戶密碼的Post請求的登陸URL[10];
(3)微博服務器收到登陸請求后進行登陸驗證,如果驗證成功就返回一個重定向的URL給客戶端,瀏覽器解析該URL后,進入登陸成功頁面并把該登陸標志寫入本地Cookies中。
1.2.2 cn版微博的模擬登陸
同樣通過Firefox和Firebug來分析手機版的登陸方式,步驟為:
(1)打開手機版登陸URL:login.weibo.cn,服務器返回一個帶有名為“mobile”用于輸入用戶名輸入框和名為“password_4位隨機數字”密碼輸入框的頁面;
(2)向微博服務器登陸URL發送一個包含明文形式的用戶名和密碼的Post請求;
(3)微博服務器對收到的登陸請求進行驗證,登陸成功后向客戶端返回一個重定向URL,并且cookie中包含gsid_CTandWM字段,瀏覽器解析該跳轉URL進入登陸成功頁面并把所有cookie字段寫入本地Cookies中[11]。
以下是通過開發包httpunit獲取手機版微博登陸cookie的Java代碼實現:
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
(1)HtmlUnitDriver hud=new HtmlUnitDriver(); //打開HtmlUnit瀏覽器
(2)hud.setJavascriptEnabled(true); //默認執行JS,如果不執行JS,則可能登錄失敗,因為用戶名密碼框需要JS代碼來繪制
(3)hud.get(“http://login.weibo.cn/login/”);//請求進入登陸頁面
(4)WebElement mobile=hud.findElementByCssSelector("input[name=mobile]");//獲取用戶名輸入框
(5)mobile.sendKeys(new CharSequence[] {username});//輸入用戶名
(6)WebElement pwd=hud.findElementByCssSelector("input[name^=password]");//獲取密碼輸入框,名字以“password_”開頭后面拼接4位隨機數字
(7)pwd.sendKeys(new CharSequence[] {password});//輸入密碼
(8)submit.click(); //點擊按鈕提交輸入
(9)Set
1.3爬取手機版微博網頁
1.3.1 瀏覽器中注入cookie
在請求微博網頁方面,在啟動httpclient瀏覽器代理時,把1.2節通過html獲取到的cookieSet注入進去。htmlunit底層也是實現httpclient的,所以直接通過httpclient請求頁面,方便而高效。
代碼功能流程是,循環迭代出cookieSet集合中所有cookie鍵值對,并把它用BasicClientCookie對象包裝后存進CookieStore對象中,最后在創建httpclient瀏覽器時把CookieStore對象添加進去。
import org.openqa.selenium.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
Cookie cookie;
BasicClientCookie bcCookie;
CookieStore cookieStore=new BasicCookieStore();
for (Iterator
cookie=(Cookie) iterator.next();
bcCookie=new BasicClientCookie(cookie.getName(), cookie.getValue());
bcCookie.setVersion(0);
bcCookie.setDomain(".weibo.cn");
bcCookie.setPath("/");
cookieStore.addCookie(bcCookie);
}
CloseableHttpClient httpClient=HttpClients.custom().setDefaultCookieStore(cookieStore).build();
1.3.2 獲取微博頁面源代碼
要想進行數據提取,必須從微博服務器中獲取到具體的網頁源代碼。通過httpclient獲取微博HTML源代碼的具體流程是:把要訪問的URL傳給要執行的Get請求(因為單純訪問簡短URL,用Get請求更合適);然后執行Get請求,服務器返回一個響應對象,通過該對象獲取到具體的HTML源碼htmlSource。
import org.apache.http.client.methods.HttpGet;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
HttpGet httpGet.setURI(new URI(URL));
CloseableHttpResponse httpResponse=httpClient.execute(httpGet);
HttpEntity httpEntity=httpResponse.getEntity();
String htmlSource=htmlSource=EntityUtils.toString(httpEntity);
1.4主題關鍵詞匹配
通過某一個主題的關鍵詞來匹配相關微博,如果合適的就加入該主題的數據庫表中,并返回該條微博包含的關鍵詞字符串[12]。篩選出與蚊子叮咬傳播疾病有關的微博,所設置的關鍵詞有登革熱、瘧疾、虐原蟲、乙腦、乙型腦炎、絲蟲。
如果獲取到的跟主題相關的微博數量太少,可以通過組拼http://weibo.cn/search/mblog?keyword=‘關鍵詞’&page=n,來獲取指定關鍵詞按照發布時間排序的微博。
public string getKeywords(String weiboContent){
String[] keywords={‘登革熱’,‘瘧疾’,‘虐原蟲’,‘乙腦’,‘乙型腦炎’,‘絲蟲病’};
String containsKeyword=new String(“”);
for(int i=0;i if(weiboContent.contains(keywords[i])) containsKeyword+=keywords[i]+“;”; } return containsKeyword; } 1.5任務調度控制 1.5.1 URL隊列 在存放URL的隊列中,必須要維護待爬隊列和已爬隊列。待爬隊列是存放尚未爬取過的新URL。已爬隊列存放已經爬取過的URL。已爬隊列的作用主要是去重處理,當有新URL準備添加進待爬隊列前,判斷該URL是否存在于在其中一個,如果已存在,則把該新URL不加進待爬隊列。初始化待爬隊列,添加微博名人堂URL作為種子URL開始爬取[13]。 (1)待爬隊列。 采用Berkeley Database(BDB)構建待爬隊列,因為從源碼中提取的待爬URL數量太大,而且數據又簡單,使用URL的MD5的值的十六進制字符串作為BDB的key,而value則使用待爬URL(CrawlURL.java)的對象。 URL對象字段至少應包括: private String oriURL; //原始URL的值,主機部分是域名 private int layer; //爬取的層次,從種子開始,依次為第0層,第1層… 待爬隊列中提供的使用接口: public CrawlURL getNext();//獲取下一條鏈接并把它從隊列中移除 public boolean putURL(CrawlURL url);//往隊列中添加一條URL (2)已爬隊列。 在企業級搜索引擎中,常用一個稱為Bloom Filter(BF)的算法實現對已抓取過的URL進行去重處理。 BF會根據大概要存儲的數據量,建立一個java.util.BitSet對象(一個很長的二進制常量),并將所有位設置為0。對每個URL,用k個不同的隨機數產生器(F1,F2,…,Fk)產生k個信息指紋(f1,f2,…,fk)。再用一個隨機數產生器G(把信息指紋變成一個0到BitSet大小的隨機數)把這k個信息指紋映射到BitSet對象中對應的k個自然數g1,g2,…,gk?,F在把這k個位置的二進制位全部置為1。 1.5.2 爬取過程控制 (1)爬取頻率控制。 新浪微博除了對微博API的調用次數進行了限制,同樣對用戶正常訪問也進行了訪問限制。實際操作中,如果微博爬蟲訪問過于頻繁,微博賬號或者網絡IP會被進行封停操作,降低抓取頻率,時間設置長一些,訪問時間采用隨機數,所以要控制好單個IP的訪問頻率。 (2)URL權重控制。 因為微博URL是動態更新的,對已經爬取過的URL,一段時間后,頁面的數據會發生變化,所以已爬取過的URL不能一直存放于已爬隊列中,而且已爬隊列是采用內存結構存儲的布隆過濾器,如果不定期清理部分URL,內存會產生溢出。根據計算機內存的大小控制好已爬隊列URL的數量,一旦數量過多,應該清理等待釋放時間最短的那部分URL。根據URL類型,判斷重要性,比如:粉絲量大、新聞類微博、明星等這些用戶較為重要,對每個URL設置一個權值,權值越大,設置在已爬隊列中的存放時間越短,并把它添加進一個特殊的URL隊列中。因為這些URL中的微博是更多人閱讀和關注的,成為熱門微博的可能性更大,所以定期對其進行訪問,不錯失第一時間抓取這類微博的機會。爬取用戶前多少頁微博或者判斷發布時間,如果發布時間過于久遠,就停止爬取該用戶的微博。同時爬取被關注的用戶,用戶的粉絲,也指定爬取前多少頁。 數據提取是從html源碼中提取需要數據的環節。通過Firebug查看微博html源碼,可以發現html源碼中的結構和編寫規則的特點,利用這些特點進行數據提取與篩選。主要功能有:微博用戶資料信息的提取、微博信息的提取、新URL的獲取、關系用戶的獲取。 把1.3.2節獲取到的html源碼htmlSource傳入htmlparser,利用過濾節點和獲取節點文本的功能,結合正則表達式的字符串匹配功能,實現數據的提取操作。 import org.htmlparser.*; Parser parser=new Parser(htmlSource); NodeFilter titleFilter=new NodeClassFilter(TitleTag.class); NodeFilter divFilter=new NodeClassFilter(Div.class); NodeFilter[] filters={titleFilter,divFilter}; NodeFilter orFilter=new OrFilter(filters); NodeList nodeList=parser.extractAllNodesThatMatch(orFilter); 2.1微博用戶資料的信息提取 微博用戶的資料信息,比如:已發布微博數量、關注他人數量、粉絲數量,都出現在第一個 觀察微博發布日期的形式有:多少分鐘前、今天 時:分、幾月幾日 時:分、年-月-日 時:分:秒,把所有發布日期統一轉換成“年-月-日 時:分:秒”這種java.sql.Timestamp格式進行存儲。 2.3新用戶獲取與URL組拼 通過對關注用戶和粉絲用戶的獲取,可以把所有用戶組建成若干個網絡關系社團。想要獲取某個用戶關注的人,可以組拼URL為:http://weibo.cn/uid/follow?page=n,想要獲取粉絲,可組拼URL為:http://weibo.cn/uid/fans?page=n。其中uid是該用戶的id,n是結果列表的頁號。然后可以從這些結果頁面中提取出大量的用戶ID和昵稱。 3.1采集性能比較與分析 當網絡足夠好時,將cn版微博爬蟲與文獻[10]中的新浪微博API、傳統爬蟲、網頁版微博爬蟲的爬取效率進行比較,如圖2所示。 圖2 不同方案采集用戶信息和采集微博的速率比較 可以看到,cn版微博爬蟲在效率上高于其他類型的微博采集方式[15]。 3.2蚊子叮咬傳播疾病的數據分析 根據匹配關鍵詞登革熱、瘧疾、虐原蟲、乙腦、乙型腦炎、絲蟲提取出的相關微博,然后根據發布時間篩選出屬于2011年1月到2015年11月的微博總數共850 794條,具體分布如表1所示。 表1 文字叮咬疾病相關微博分布比例 經過統計,包含關鍵詞登革熱的微博有395 976條,包含瘧疾或瘧原蟲的有292 843條,占比例46.781%;包含乙腦或乙型腦炎的有141 691條,絲蟲病的微博有20 274條,可知跟蚊子有關的微博主要是登革熱和瘧疾。 將所有微博按照時間段從2011年1月到2015年11月,然后按微博發布的月份進行分類統計,可以得到每個月相關微博數量和相關參與用戶的數量,如圖3和圖4所示。 圖3 與蚊子叮咬傳播疾病微博 圖4 相關微博的用戶參與數量 圖4統計出了每個月份發布微博對應用戶的數量,該用戶數量是經過重復性去除后產生的,即找到該月每條微博對應的發布者后,判斷該用戶是否被統計過,如果已經被統計過,則不再統計。例如,在某個月的多條微博屬于同一個用戶發布,但是該用戶只統計一次。 從圖3和圖4可以看出,2014年6-8月與2015年5、9、10月分別出現了一個最大的和較大的波峰,表明這一期間用戶對蚊子叮咬產生的相關疾病較為關注。而現實中的情況是,2014年6月,印度東北部和廣州同時爆發嚴重的感染登革熱病例的疫情;2015年5月,臺灣和其他國家一些地區爆發較為嚴重的登革熱疫情;同年9月印度爆發5年來最嚴重的登革熱疫情;同年10月中國科學家屠呦呦獲得諾貝爾醫學獎,她發現的青蒿素能有效治療瘧疾,同樣引起了很多用戶關注。相關微博發布大波峰基本都是爆發登革熱疫情,從而引起用戶的參與關注,隨著時間的推移,用戶對其的關注度逐漸降低,發布的相關微博越來越少。 從數據量龐大的微博數據中采集想要的數據,擁有一個效率高、可靈活控制采集方向和主題導向的微博爬蟲至關重要。為此,采用Java結合流行的HTML源碼解析工具開發包實現了一個可以靈活控制爬取條件的微博網絡爬蟲,其采用基于手機版模擬登陸與頁面解析的方法,實現起來更加便捷。而Java實現爬蟲的代碼,對相關開發人員來說有更大的實用價值,節省了大量爬蟲代碼設計時間。利用該爬蟲系統,能更高效地對大規模微博數據,特別是最新數據,進行采集,用戶也可以結合微博API來進行數據采集,擴大微博數據的采集量,從而為微博信息的數據挖掘提供更全面、準確的數據支持。實驗結果表明,該系統有效可行,采集效率明顯優于其他幾種采集方式,且相對于微博API更靈活多變,在廣度遍歷URL方面更出色。 [1] Wen E,Sun V.新浪微博研究報告[R/OL].2011-05-20.http://www.techWeb.com.cn/data /2011-02-25/916941.shtml. [2] 高 凱,王九碩,馬紅霞,等.微博信息采集及群體行為分析[J].小型微型計算機系統,2013,34(10):2413-2416. [3] 紀 偉.微博數據采集系統的設計與實現[D].石家莊:河北科技大學,2013. [4] Han Ruixia.The influence of microblogging on personal public participation[C]//Proceedings of the 2010 IEEE 2nd symposium on web society.Beijing,China:IEEE,2010:615-618. [5] 周德懋,李舟軍.高性能網絡爬蟲:研究綜述[J].計算機科學,2009,36(8):26-29. [6] 廉 捷,周 欣,曹 偉,等.新浪微博數據挖掘方案[J].清華大學學報:自然科學版,2011,51(10):1300-1305. [7] Du Y,Zhang K,Lyu X,et al.The study of gathering and extracting users information based on micro-blog[C]//International conference on computer,mechatronics,control and electronic engineering.[s.l.]:[s.n.],2010:47-50. [8] 李超鋒,盧炎生.基于URL結構和訪問時間的Web頁面訪問相似性度量[J].計算機科學,2007,34(4):207-209. [9] 尹 江,尹治本,黃 洪.網絡爬蟲效率瓶頸的分析與解決方案[J].計算機應用,2008,28(5):1114-1116. [10] 孫青云,王俊峰,趙宗渠,等.一種基于模擬登錄的微博數據采集方案[J].計算機技術與發展,2014,24(3):6-10. [11] Lu G,Liu S,Lü K.MBCrawler:a software architecture for micro-blog crawler[C]//Proceedings of the 2012 international conference on information technology and software engineering.Berlin:Springer,2013:119-127. [12] 劉金紅,陸余良.主題網絡爬蟲研究綜述[J].計算機應用研究,2007,24(10):26-29. [13] 周中華,張惠然,謝 江.基于Python的新浪微博數據爬蟲[J].計算機應用,2014,34(11):3131-3134. [14] 羅一紓.微博爬蟲的相關技術研究[D].哈爾濱:哈爾濱工業大學,2013. [15] 朱云鵬,馮 楓,陳江寧.多策略融合的中文微博數據采集方法[J].計算機工程與設計,2013,34(11):3835-3839. Research and Realization of Weibo Crawler with Java CHEN Ke,LAN Ding-dong,KE Wen-de,LI Shu-jun,DENG Wen-tian (College of Computer and Electronic Information,Guangdong University of Petrochemical Technology,Maoming 525000,China) In order to obtain more microblog data efficiently,a Java-based acquisition system of Sina is designed and developed for Weibo API,traditional crawler and Web version (com version),by which Weibo.cn Web site crawler system has been established through the breadth combination of traverse combination to collect web page source code and thus the page source code is more concise and purer,reducing network transmission pressure and the HTML source code analysis time.It mainly realizes the Weibo simulated logging,Weibo web crawling,Weibo page data extraction and task scheduling control,and analyzes the crawling data.The theme Weibo selection is added in the crawler.To verify its effectiveness and feasibility,the analysis and comparison is made with other traditional methods.The experimental results show that it is of higher efficiency with simpler code. Sina Weibo;Web crawler;Java;data mining 2016-08-22 :2016-11-24 < class="emphasis_bold">網絡出版時間 時間:2017-07-11 國家級大學生創新創業訓練計劃項目(201411656017,201611656002,201611656029,2016pyA033);廣東省自然科學基金(2016A030307049);廣東省高等學校學科與專業建設專項資金科研類項目(2013KJCX0132);廣東省云機器人(石油化工)工程技術研究中心開放基金項目(650007) 陳 珂(1964-),男,碩士,教授,研究方向為Web數據挖掘、信息檢索;藍鼎棟(1992-),男,研究方向為Web數據挖掘、智能信息系統。 http://kns.cnki.net/kcms/detail/61.1450.TP.20170711.1452.010.html TP39 :A :1673-629X(2017)09-0191-06 10.3969/j.issn.1673-629X.2017.09.0422 cn版微博數據提取
中,可用正則表達式:matches(".*\s+src="http://.+\s+alt="圖片"\s+.*class="ib".*")進行匹配獲取。
3 實驗及結果分析




4 結束語