夏火松 李保國
摘 要:在大數(shù)據(jù)獲取中面臨著如何采集動態(tài)評論網(wǎng)頁的問題,這篇論文使用靜態(tài)網(wǎng)頁信息構(gòu)造動態(tài)鏈接,提出了基于Python的動態(tài)網(wǎng)頁評論爬蟲算法。在此基礎(chǔ)上實現(xiàn)了評論收集程序。最后將它與通用爬蟲算法進行比較,證實了該算法具有針對性強、數(shù)據(jù)采集速度快、易嵌入開發(fā)、簡單等優(yōu)點,為不善于編程的新聞、文學(xué)、管理等學(xué)科的研究者提供了快速獲取評論信息的方法。
關(guān)鍵詞:Python語言;靜態(tài)地址;動態(tài)鏈接;動態(tài)網(wǎng)頁評論;爬蟲算法
中圖分類號:TP312 文獻標識碼:A
1 引言(Introduction)
大數(shù)據(jù)具有數(shù)據(jù)體量巨大(Volume)、數(shù)據(jù)類型繁多(Variety)、價值密度低(Value)、處理速度快(Velocity)的特點。在大數(shù)據(jù)獲取中面臨的一個數(shù)據(jù)源問題為:如何獲取大量的動態(tài)評論數(shù)據(jù)?Python是一門獨立的語言,可以直接操作數(shù)據(jù)庫,便于對大規(guī)模數(shù)據(jù)的操作與分析[1]。而且,由于Python包含結(jié)巴分詞等程序包,可以直接進行分詞,適宜于自然語言處理[2]。
現(xiàn)在很多網(wǎng)頁通過Ajax動態(tài)請求、異步刷新生成數(shù)據(jù)[3]。Python由于先天局限,它爬取靜態(tài)網(wǎng)頁的方法難于直接提取動態(tài)網(wǎng)頁。而爬取動態(tài)網(wǎng)頁的方法雖然有很多,但便于新聞學(xué)、語言學(xué)、管理等學(xué)科的研究者應(yīng)用的方法卻很少。所以這篇論文研究如何用Python語言爬取Ajax動態(tài)生成的評論數(shù)據(jù)。
這篇論文延續(xù)前人的方法,通過靜態(tài)網(wǎng)址信息構(gòu)造動態(tài)鏈接,并增加了翻頁的部分,把各種商品、新聞、社交網(wǎng)站、TV等動態(tài)網(wǎng)頁評論的爬取方法歸結(jié)為一套抽象的爬蟲算法流程圖。在此基礎(chǔ)上實現(xiàn)了商品評論收集程序[4]。本文為實時評價數(shù)據(jù)采集技術(shù)的研究提供了新路徑[5]。
2 基于Python的爬蟲算法 (Reptiles algorithms
based on Python)
網(wǎng)絡(luò)爬蟲即數(shù)據(jù)采集程序。主要有搜索引擎網(wǎng)絡(luò)爬蟲[6]、基于Agent的網(wǎng)絡(luò)爬蟲、遷移的網(wǎng)絡(luò)爬蟲、通用網(wǎng)絡(luò)爬蟲和聚焦爬蟲等。其中聚焦爬蟲是一種主題網(wǎng)絡(luò)爬蟲,它圍繞主題內(nèi)容采集數(shù)據(jù)。
靜態(tài)網(wǎng)頁是指不應(yīng)用程序而直接或間接制作成Html的網(wǎng)頁,每一個頁面都有一個固定的URL地址,這個URL和相應(yīng)的Html可以通過Python直接獲取。動態(tài)網(wǎng)頁一般使用腳本語言(Php、Asp等)將網(wǎng)站內(nèi)容存于數(shù)據(jù)庫中,相應(yīng)URL動態(tài)鏈接不可以通過Python獲取。但是動態(tài)URL的變化部分一般可以在相關(guān)靜態(tài)URL及源代碼中尋找,所以這篇論文在前人的基礎(chǔ)上,利用靜態(tài)的URL地址和相應(yīng)的網(wǎng)頁源代碼構(gòu)造動態(tài)鏈接,從而實現(xiàn)了Python直接對動態(tài)網(wǎng)頁的爬取。本研究在前人基礎(chǔ)上,通過對各主流商品、新聞、社交網(wǎng)站、TV等動態(tài)網(wǎng)頁評論分析,提出了基于Python的動態(tài)網(wǎng)頁爬蟲算法流程圖,如圖1所示。
3 相關(guān)操作與爬蟲程序(Operation and Reptiles
procedure)
為顧及新聞、管理等的學(xué)科的研究者,相關(guān)操作比較詳細。工具:使用Chrome瀏覽器的開發(fā)人員工具或火狐瀏覽器的Firebug插件,這篇論文以Firebug插件為例[7]。首先安裝火狐瀏覽器,版本為40.0,并裝上Firebug,版本為2.0.13。程序以商品評論為例,具體分五步。
3.1 靜態(tài)URL構(gòu)造動態(tài)URL
(1)提取某個商品的靜態(tài)URL網(wǎng)址
該文以商品為例,用瀏覽器打開某個商品的頁面,復(fù)制地址欄網(wǎng)址如①所示。
http://item.jd.com/492036.html①
(2)提取對應(yīng)評論頁的靜態(tài)URL
a.單擊“商品評價”;b.復(fù)制地址欄的網(wǎng)址如②所示。
http://item.jd.com/492036.html#comment②
(3)提取含有評論數(shù)據(jù)的Ajax動態(tài)鏈接
這里總結(jié)前人獲取評論動態(tài)鏈接的方法如下:a.用火狐瀏覽器在評論頁空白部分,右鍵——使用Firebug查看元素,打開“Firebug工作面板”;b.點擊工具面板上的“網(wǎng)絡(luò)”;c.其子菜單默認在“全部”處;d.單擊工作面板左上角的“清除”,以清除已有請求;e.在瀏覽器窗口中,點擊評論第二頁的圖標;f.在“Firebug工作面板”上,右擊"GET p-492036-……"這個動態(tài)請求,然后點擊“復(fù)制地址”;其中,選定"GET p-492036-……"這個請求的原因為:這個請求的“響應(yīng)”含有評論數(shù)據(jù);g.粘貼這個“第二頁”評論的動態(tài)地址如③所示。
http://club.jd.com/productpage/p-492036-s-0-t-3-p-1.html?callback=fetchJSON_comment98vv216③
通過動態(tài)網(wǎng)址③就可以得到第2頁的評論。獲取動態(tài)鏈接的操作如圖2所示。
動態(tài)網(wǎng)址③含有一些時間戳等無用部分,可以進行適當?shù)暮喕?。簡化方法為:將網(wǎng)址③粘貼到瀏覽器地址欄,在保證網(wǎng)頁結(jié)果保留JSON格式信息的前提下,按照分隔符逐個刪除,直到最簡,如④所示。
http://club.jd.com/productpage/p-492036-s-0-t-3-p-1.html④
(4)提取存儲評論數(shù)據(jù)的另一頁的Ajax動態(tài)鏈接
操作和3.1的第3節(jié)相同,但是,在其中的第5部分,應(yīng)該點擊評論的第三頁。最后得到第三頁評論的動態(tài)網(wǎng)址,并簡化如⑤所示。
http://club.jd.com/productpage/p-492036-s-0-t-3-p-2.html⑤
(5)提取另外一個商品的已簡化的Ajax動態(tài)鏈接如⑥所示
http://club.jd.com/productpage/p-1298665-s-0-t-3-p-1.html⑥
(6)根據(jù)靜態(tài)網(wǎng)頁信息構(gòu)造Ajax動態(tài)鏈接
分析④⑤⑥動態(tài)網(wǎng)址的變化部分,找出組成結(jié)構(gòu)如⑦所示
http://club.jd.com/productpage/p-+商品ID+-s-0-t-3-p-+頁碼標識+.html⑦
“商品ID”唯一標識了這個商品,“頁碼標識”表示不同的頁碼。在Ajax動態(tài)鏈接的組成結(jié)構(gòu)中,對于變化部分,一般可以在靜態(tài)網(wǎng)址①②以及由①②所得到網(wǎng)頁的源代碼中尋找,其中獲取源代碼方法:網(wǎng)頁空白處右鍵單擊——查看網(wǎng)頁源代碼。而對于這個網(wǎng)站,“商品ID”可以由靜態(tài)網(wǎng)址①得到,“頁碼標識”一般為1…N的自然數(shù)。這樣就可以由商品的靜態(tài)網(wǎng)址及網(wǎng)頁數(shù)據(jù)構(gòu)造出評論的動態(tài)鏈接,從而爬取評論信息。
一般在一種網(wǎng)站中,不同商品對應(yīng)的評論頁動態(tài)網(wǎng)址⑦的格式是相同的。所以可以選擇某一個商品的動態(tài)評論網(wǎng)址,設(shè)置為標準動態(tài)網(wǎng)址(comment_Norm),為方便起見,這篇論文把網(wǎng)址④設(shè)置為comment_Norm。這樣,對于任意一種商品,把comment_Norm的商品ID置換為本商品的ID,就可以得到這個商品的動態(tài)網(wǎng)址;置換頁數(shù),可以得到2…N頁的動態(tài)網(wǎng)址(commentsUrl),因為第1頁的動態(tài)網(wǎng)址不易獲取,所以從第2頁開始爬取。
3.2 獲取該Ajax請求返回的Json數(shù)據(jù)
用requests的get/post方法(或urllib、urllib2、beautifuSoup等)發(fā)送請求并接收數(shù)據(jù):content=requests.get(comments_Url).content。用正則表達式提取標準數(shù)據(jù):content='{'+re.findall(r"{(.+)}",content)[0]+'}'。然后轉(zhuǎn)換為Json庫函數(shù)可以處理的字典格式:dict=json.loads(content,"gbk"),其中“gbk”為這個網(wǎng)頁的數(shù)據(jù)編碼方式,Python默認編碼方式為“Ascii”,當網(wǎng)站編碼方式也為“Ascii”時,直接用json.loads(content)。
3.3 解析Json數(shù)據(jù)并保存結(jié)果
(1)解析Json數(shù)據(jù)
使用Python IDE即PyCharm解析Json數(shù)據(jù),PyCharm版本4.0.5,python版本2.7.10。操作為:a.在dict=json.loads(content,"gbk")這句設(shè)置斷點;b.點擊“Debug/綠色甲蟲”圖標;c.點擊“Step Over”;d.在“Variables”中右擊“dict”變量;e.左鍵單擊“add to watches”;f.在“Watches”窗口中點擊“dict”變量前的三角符號,就得到了dict的樹狀結(jié)構(gòu)。操作如圖3所示。
也可以使用一般瀏覽器的“FeHelper”插件解析Json數(shù)據(jù),“FeHelper”插件版本v7.5。操作:把3.1的第3節(jié)的第6部分的“Response/響應(yīng)”復(fù)制粘貼到FeHelper的“Json串格式化”的窗口中,單擊格式化。也可以直接用Firebug插件,操作:在在3.1的第3節(jié)的第6部分,點擊含有評論數(shù)據(jù)的響應(yīng)——單擊“JSON”按鈕。在“JSON”內(nèi),即為Json數(shù)據(jù)的樹狀結(jié)構(gòu),如圖2所示。
(2)尋找評論路徑
dict['comments'][j]['content']即為評論,j為0-9自然數(shù)。
(3)保存結(jié)果
用easy_install或者是pip安裝相應(yīng)python包,以及安裝對應(yīng)的數(shù)據(jù)庫軟件。結(jié)果可以保存到mysql[8]、csv、excel、mongodb等數(shù)據(jù)庫中。
3.4 停止條件
一般通過評論總頁數(shù)判斷,可以直接看有多少頁(京東商城、國美在線等);或則用評論總數(shù)除以每頁個數(shù)得到總頁碼(天貓網(wǎng)、淘寶網(wǎng)、當當網(wǎng)、亞馬遜卓越網(wǎng)、蘇寧易購等)?;蛲ㄟ^判斷動態(tài)鏈接請求的返回值是否為空作為停止條件。
3.5 程序及結(jié)果
最后構(gòu)造程序如圖4所示。
3.6 特殊情況
(1)自動獲取停止爬取的標志
一般需要從含有評論數(shù)據(jù)的動態(tài)網(wǎng)頁或其他動態(tài)網(wǎng)頁中尋找相關(guān)數(shù)據(jù)。a.通過評論總頁數(shù):例如淘寶網(wǎng),dict['maxPage']即為總頁數(shù)。b.通過評論總數(shù):例如京東商城的dict['productCommentSummary']['commentCount']為評論總個數(shù),再除以每頁的個數(shù),即得到總頁數(shù)。c.通過停止標志:例如騰訊TV、騰訊新聞。它們的停止標志為dict['data']['hasnext'],該值如果為false,則應(yīng)停止爬取。
(2)頁碼標志符不是自然數(shù)
標志符一般需要從相關(guān)動態(tài)網(wǎng)頁中尋找。例如騰訊新聞、TV。首先選取某個新聞,提取第一頁已簡化的動態(tài)評論網(wǎng)址如⑧所示,提取第二頁的如⑨所示,動態(tài)網(wǎng)址的結(jié)構(gòu)見⑩。
http://coral.qq.com/article/1267477591/comment?commentid=0&reqnum=10⑧
http://coral.qq.com/article/1267477591/comment?commentid=6081308797779398298&reqnum=20⑨
http://coral.qq.com/article/+新聞ID+/comment?commentid=+pageID+&reqnum=+rNUM⑩
“新聞ID”從評論頁靜態(tài)網(wǎng)址中提??;第1頁評論動態(tài)網(wǎng)頁的“rNUM”為10,第2…N頁的“rNUM”為20;第1頁的“pageID”為固定值“0”,其他頁的“pageID”從前一頁的動態(tài)網(wǎng)頁中找,其中pageID=dict['last']。以此類推,這樣就可以得到第1…N頁的動態(tài)網(wǎng)址了。
其中第一頁動態(tài)網(wǎng)址的獲取方法為:進入評論頁,打開“Firebug工作面板”,單擊“清除”,然后刷新頁面,在請求中逐個尋找。存儲評論的請求一般包含在“網(wǎng)絡(luò)”子菜單的JavaScript或XHR中,可以直接在這里找。
(3)遵守robot協(xié)議
在爬取數(shù)據(jù)的過程中,應(yīng)嚴格遵守網(wǎng)絡(luò)協(xié)議規(guī)定,經(jīng)測試,6秒對服務(wù)器發(fā)起一次請求較為合適。用time.sleep(6)來控制速度。
(4)應(yīng)對防爬蟲方法
a.表頭信息:對于一些網(wǎng)站需要表頭信息,程序為:content=requests.get(comments_Url,headers=header).content。其中的comments_Url為存儲評論信息的動態(tài)網(wǎng)址。Header為表頭信息,獲取方法為:在3.1的第3節(jié)的第6部分點擊任意一個請求—頭信息—請求頭信息—“User-Agent”。b.cookie:對于一些需要登錄信息的網(wǎng)站,例如新浪/騰訊微博、twitter、QQ空間、Facebook、朋友網(wǎng)、人人網(wǎng)、網(wǎng)頁版微信/來往等,需要Cookie信息。程序為:content=requests.get(comments_Url,cookies=cook).content。Cookie的獲取方法為:先用瀏覽器登錄賬號,在3.1的第3節(jié)的第6部分點擊含有評論信息的請求—頭信息—請求頭信息—Cookie。c.Form Data(表單數(shù)據(jù)):例如鳳凰新聞、TV評論,由評論頁動態(tài)網(wǎng)址并不能得到評論數(shù)據(jù),還得加入Form Data,而且通過更改表單數(shù)據(jù)中'p'的值來翻頁。程序如下:
comments_Url='http://comment.ifeng.com/get?job=1&order=DESC&orderBy=create_time&format=json&pagesize=20'
data={'p':'1','docurl':'http://news.ifeng.com/a/20151121/46335318_0.shtml'}
content=requests.post(comments_Url,data=data).content
data為表單數(shù)據(jù)的信息。獲取方法為:在3.1的第3節(jié)的第6部分點擊含有評論信息的請求—Post—參數(shù)。
(5)其他
環(huán)球新聞用content=re.findall(r"comment_list\((.+)\);",content)[0]語句提取標準Json數(shù)據(jù)。新浪、騰訊等網(wǎng)站,評論不分頁顯示,“加載更多/加載更多評論”按鈕相當于第2…N頁。優(yōu)酷TV,動態(tài)鏈接返回Html。用正則表達式提取評論信息。對評論部分的字符串(例如:comment="\u559c\u6b22\u59ae"),用comment=comment.decode("unicode-escape")進行反編碼后得到對應(yīng)漢字。
4 對比分析(Comparative analysis)
該研究把本文所設(shè)計的爬蟲與目前應(yīng)用廣泛的通用爬蟲比較:通用爬蟲以集搜客和網(wǎng)絡(luò)神采為例。網(wǎng)絡(luò)神采通用性最強(采集瀏覽器看到的),采集內(nèi)容范圍廣(支持登錄、跨層、POST、腳本、動態(tài)網(wǎng)頁),但需要設(shè)置許多參數(shù);基于Python的動態(tài)網(wǎng)頁評論爬蟲專門針對評論,而且爬取過程不依賴于瀏覽器,因此其效率比集搜客和網(wǎng)絡(luò)神采快些。在復(fù)雜度方面,網(wǎng)絡(luò)神采考慮的因素比較全面,所以比評論爬蟲算法復(fù)雜得多;而集搜客,基本不用編寫程序,甚至直接使用現(xiàn)成的采集規(guī)則。網(wǎng)絡(luò)神采擴展性強(支持存儲過程、插件、二次開發(fā)),集搜客可以導(dǎo)入excel,而Python可操作各種DB。三種爬蟲對比分析詳見表2。
5 結(jié)論(Conclusion)
研究在前人的基礎(chǔ)上,設(shè)計了基于Python的商品、新聞、社交網(wǎng)站、TV評論聚焦爬蟲算法。以此為基礎(chǔ),實現(xiàn)了商品評論的收集程序?;赑ython的評論爬蟲具有一定的高效性、通用性、實時性,所以可以作為實時商品、新聞、社交網(wǎng)站、TV評論采集算法;這種算法基于自然語言處理能力強的Python語言,利于對評論文本的后續(xù)分析以及相應(yīng)爬蟲軟件[9]的開發(fā)。而且這種爬蟲比較簡單,可以被計算機基礎(chǔ)弱的評論挖掘研究者使用。
參考文獻(References)
[1] 彭磊,李先國.大數(shù)據(jù)量Excel數(shù)據(jù)導(dǎo)入系統(tǒng)的設(shè)計與實現(xiàn)[J].
計算機應(yīng)用技術(shù),2014(14):57-59.
[2] 吳宏洲.分詞技術(shù)的研究與應(yīng)用——一種抽取新詞的簡便方
法[J].軟件工程師,2015,18(12):64-68.
[3] 王佳.支持Ajax技術(shù)的主題網(wǎng)絡(luò)爬蟲系統(tǒng)研究與實現(xiàn)[D].北
京:北京交通大學(xué),2011:22-27.
[4] 方美玉,鄭小林,陳德人.商品評論聚焦爬蟲算法設(shè)計與實現(xiàn)
[J].吉林大學(xué)學(xué)報(工學(xué)版),2012(S1):377-381.
[5] 陳國良.基于商品評論信息的特征挖掘[J].福建電腦,2015(05):
106-107.
[6] 劉典型.基于概念聚類的Web數(shù)據(jù)挖掘搜索引擎的設(shè)計與實
現(xiàn)[J].軟件工程師,2015,18(5):18-20.
[7] Winterto1990.python爬取ajax動態(tài)生成的數(shù)據(jù)以抓取淘寶
評論為例子[EB/OL].[2015-08-26]http://www.th7.cn/web/
ajax/201508/117293.shtml.
[8] 陳瀟.SQL Server2008數(shù)據(jù)庫存儲過程的應(yīng)用[J].軟件工程師.
2015,18(6):18-19.
[9] 劉正春.基于Carbide.C++的Symbian OS軟件開發(fā)[J].電腦與
電信,2009(01):47-49.
作者簡介:
夏火松(1964-),男,博士,教授.研究領(lǐng)域:決策支持系統(tǒng).
李保國(1990-),男,研究生.研究領(lǐng)域:信息管理.