金 林,李 研,陳晉泰
(中南財經(jīng)政法大學(xué) 統(tǒng)計與數(shù)學(xué)學(xué)院,武漢430073)
當(dāng)前在統(tǒng)計學(xué)和大數(shù)據(jù)領(lǐng)域流行的R軟件具備強大獲取數(shù)據(jù)的能力,而且表現(xiàn)出高效性、方便性和針對性等特點。R中擁有大量與網(wǎng)絡(luò)數(shù)據(jù)收集相關(guān)的包,通過調(diào)用電腦系統(tǒng)的組件,可以完成各種數(shù)據(jù)搜集的工作,十分高效。從方便性的角度說,搜集到的數(shù)據(jù)還可以直接在R的平臺上處理,簡化了整個數(shù)據(jù)分析工作流程;同時,R還善于處理數(shù)據(jù)的存儲,RMySQL和RHadoop等包可以與MySQL、Hadoop等數(shù)據(jù)庫進行交互,為大規(guī)模數(shù)據(jù)存儲和提取提供了條件;與當(dāng)下一些流行的菜單式操作的爬蟲軟件相比,R的數(shù)據(jù)搜集工作更具有針對性,旨在搜集特定網(wǎng)站的特定數(shù)據(jù),而并非像有些爬蟲在網(wǎng)頁中跳躍,跟蹤網(wǎng)絡(luò)足跡等,這樣一來收集到的數(shù)據(jù)就可以更好地為后面的統(tǒng)計分析服務(wù)。
使用R進行數(shù)據(jù)的自動化搜集,主要涉及兩個方面的工作:一是如何在不同情況下,從網(wǎng)絡(luò)服務(wù)器中檢索到所要的資源,這個工作涉及到的關(guān)鍵技術(shù)是HTTP協(xié)議的相關(guān)知識;二是如何從已經(jīng)得到的資源中提取信息,大部分表現(xiàn)為對網(wǎng)絡(luò)文檔的操作。但是,不論抓取的信息有多么復(fù)雜,抓取的流程都離不開以下基本步驟:
(1)資源識別
資源識別是決定搜集策略的前提。資源識別需要做以下幾個工作:確定目標(biāo)數(shù)據(jù)所在網(wǎng)頁及形式——是通過API獲取還是通過URL訪問網(wǎng)頁獲??;若是后者,其具體的URL(網(wǎng)頁地址)是什么,存在于單個網(wǎng)頁還是需要翻頁;如需翻頁,是否改變URL,抑或只能通過JavaScript控制翻頁。而若是利用API獲取的方法,API接口是免費開源的還是需要OAuth授權(quán)的。
當(dāng)成功登陸網(wǎng)站之后,目標(biāo)數(shù)據(jù)是否以存在于現(xiàn)成的下載鏈接中?若其他情形,要視其數(shù)據(jù)存在于表格、列表中?是否需要通過表單的提交來獲取數(shù)據(jù)?
當(dāng)這些都確定了之后,還需要判斷的是,是否目標(biāo)信息在某個網(wǎng)絡(luò)文檔的節(jié)點中?還是在某個節(jié)點中的某個屬性里?甚至僅僅是某個節(jié)點或者某個屬性的一部分?
除此之外,還有一些細節(jié)的信息,例如網(wǎng)站數(shù)據(jù)的編碼形式。這些細節(jié)則貫穿于每一個步驟中,需要數(shù)據(jù)搜集者留意。當(dāng)了解了這些信息以后,資源識別才算基本完成。
(2)策略選擇
資源識別之后,需要根據(jù)資源識別結(jié)果選擇數(shù)據(jù)搜集的方法。一般而言,這些方法離不開一些網(wǎng)絡(luò)相關(guān)工具的基礎(chǔ)知識:例如HTTP和FTP協(xié)議的訪問知識,HTML網(wǎng)頁的結(jié)構(gòu)、XML文檔結(jié)構(gòu)、JSON文檔結(jié)構(gòu)的基本知識以及處理方式;當(dāng)目標(biāo)信息值在于某個節(jié)點、節(jié)點屬性、甚至是節(jié)點屬性的一部分中,還需要掌握XPath,正則表達式等提取工具的相關(guān)知識。
(3)信息抓取
當(dāng)確定了策略,并確定使用R進行數(shù)據(jù)搜集,還需掌握R語言基礎(chǔ),R的XML,RCurl,RSelenium,httr,rvest等軟件包,以及其中的函數(shù)。每一個函數(shù)都有對應(yīng)的功能,注意其中的參數(shù)細節(jié)會左右抓取最終結(jié)果。
(4)通用化設(shè)計
通用化設(shè)計是一個比較高的層次。數(shù)據(jù)信息往往分散在不同頁面或者同一頁面的某幾處,如何抓住其特征來制定可通用的搜集方式,需要操作者細致的觀察和過硬的技術(shù)。經(jīng)過通用化設(shè)計,一段代碼可以重復(fù)運行于不同網(wǎng)頁,可以極大減輕工作量。
其完整流程可以用圖1表示。
圖1 R軟件網(wǎng)絡(luò)數(shù)據(jù)搜集流程圖
(1)HTTP協(xié)議
HTTP是超文本傳輸協(xié)議(HyperText Transfer Protocol),是互聯(lián)網(wǎng)中最廣泛使用的傳輸協(xié)議。此外,常用的傳輸協(xié)議還有FTP(文件傳輸協(xié)議)等。HTTP幾乎可以傳輸任何形式的資源。在HTTP傳輸?shù)男畔⒅?,需要?shù)據(jù)搜集操作者注意的是,其網(wǎng)頁信息獲?。ɑ蛱峤唬┑姆椒ㄖ?,最常用的有兩種:GET方法和POST方法。GET方法的特點是數(shù)據(jù)的傳輸都是通過URL,所以長度有所限制,但也因為如此較為方便;POST方法傳輸是通過文檔正文傳輸?shù)?,容量較大。HTTP傳輸協(xié)議在傳輸過程中,需要與服務(wù)器交換包括訪問者、訪問平臺、來源、訪問記錄、網(wǎng)頁狀態(tài)結(jié)果等各種信息。在R中,具體可以通過RCurl包中的getCurlHandle()函數(shù)來構(gòu)造并提交信息。
(2)XML包對HTML的基本處理
HTML是網(wǎng)頁結(jié)構(gòu)標(biāo)準架構(gòu),全稱是超文本標(biāo)記語言(Hyper Text Markup Language),用于展示網(wǎng)頁結(jié)構(gòu)內(nèi)容,其特色是嵌套式的標(biāo)記結(jié)構(gòu)。HTML的標(biāo)記結(jié)構(gòu)將網(wǎng)頁文本組織起來,用以指定文本中的某些特定結(jié)構(gòu)部分:如標(biāo)題、鏈接、內(nèi)容、表格等,用來告訴“網(wǎng)頁解析器”(用于解析網(wǎng)頁源代碼)網(wǎng)頁文檔各個部分的作用和展示方式,仿佛是承載整個網(wǎng)頁信息的“貨架”。要看懂HTML,重要的是要看懂它的標(biāo)簽——各個標(biāo)簽通過層層嵌套或并列的方式組織了HTML。常見的HTML標(biāo)簽有
處理HTML和XML一樣,常常可以解析為DOM樹。DOM樹全稱是文檔對象模型(Document Object Model),可以被簡單理解為“用樹形圖的形式將節(jié)點元素標(biāo)簽組織起來”。它將網(wǎng)頁中的各個元素看作各個對象,故而能被單獨提取和編輯。基于這個特點,對于節(jié)點標(biāo)簽的操作,常常將其解析為DOM樹。
XML包是R中網(wǎng)頁信息提取的主要軟件包,有著各類網(wǎng)絡(luò)文檔處理函數(shù)。對于HTML,常見的處理方式有節(jié)點選擇與丟棄。將HTML解析為DOM以后,將無用的節(jié)點丟棄,就得到有用的節(jié)點。例如想得到網(wǎng)頁源代碼的
(3)XML包對XML文檔的基本處理
XML文檔和HTML文檔作用不同:HTML主要用于展示數(shù)據(jù),XML文檔則主要是用以存放數(shù)據(jù)。但從形式上看,二者十分相似,都是層層嵌套的形式,不允許交叉嵌套。不同的是XML標(biāo)簽內(nèi)容可以自定義。任何標(biāo)簽名稱都是允許的,只要將他們按照層次嵌套起來即可。只要理解了HTML,理解XML文檔相當(dāng)容易。
同HTML一樣,XML也可以解析為DOM樹,再通過操作每一個節(jié)點標(biāo)簽內(nèi)的內(nèi)容完成提取。R中XML文檔專用的解析函數(shù)是xmlParse()。此外,XML還有一個特殊的函數(shù):xmlRoot(),它通過尋找根節(jié)點的方式將解析后的XML結(jié)構(gòu)化,按照其標(biāo)簽嵌套層次將XML細分。這樣節(jié)點層次、節(jié)點數(shù)量、嵌套模式,十分清晰:每一個節(jié)點都被清楚的分離便于定位,因此操作也變得相當(dāng)容易。
(4)RJOSNIO包對JOSN文檔的基本處理
JSON文檔同XML文檔一樣,都可以用于存儲網(wǎng)絡(luò)數(shù)據(jù),JSON常用于網(wǎng)絡(luò)應(yīng)用接口API,一般比XML更輕量。相比之下,XML格式統(tǒng)一,更容易與其他系統(tǒng)進行遠程交互和數(shù)據(jù)共享,但XML文件更龐大而且結(jié)構(gòu)復(fù)雜,需要占用更多的存儲空間。JSON的格式數(shù)據(jù)較簡單,方便網(wǎng)絡(luò)存儲和讀取。
R中的RJOSNIO、rjson、jsonlite包都可以用來處理JOSN格式的文檔,其中RJOSNIO最為常用。RJOSNIO中的fromJSON()函數(shù)可以用來將JSON的內(nèi)容,按照其結(jié)構(gòu)層次劃分為列表,且每個層次都支持編輯。當(dāng)訪問列表中的每一層,便能找到所需要的信息。
不論是HTML,XML還是JSON,都是有一定結(jié)構(gòu)層次的文檔。而R軟件在解析它們并提取數(shù)據(jù)的時候,不論面對何種文檔、使用何種方法,無不是建立在其結(jié)構(gòu)性特點的基礎(chǔ)上,將他們按照結(jié)構(gòu)節(jié)點分離成列表或其他形式,讓這些部分都接受直接編輯,而使得操作者可以獲得所需信息。
(5)正則表達式
正則表達式將文本視為無規(guī)則結(jié)構(gòu)(即直接看成是字符的堆疊),按照正則表達式的匹配規(guī)則,從文檔中匹配出其符合規(guī)則的內(nèi)容。正則表達式有各種元字符,如、^、$、?等。是否使用正則表達式需關(guān)注:目標(biāo)數(shù)據(jù)之間是否由明顯的共同點,而與非目標(biāo)數(shù)據(jù)之間是否由明顯的區(qū)別。
正則表達式抓取網(wǎng)頁內(nèi)容有其獨特優(yōu)點:它能對非標(biāo)準格式的網(wǎng)頁源代碼進行處理;另外,也能適用于網(wǎng)頁抓取后的冗雜信息處理工作。從另一角度看,正則表達式的使用的劣勢在于,當(dāng)“網(wǎng)頁結(jié)構(gòu)”也是必要信息時,正則表達式在操作過程中將其破壞了。因此,正則表達式的最佳使用場景應(yīng)該是在常規(guī)辦法無能為力的不規(guī)則網(wǎng)頁中與數(shù)據(jù)形態(tài)清理工作,如字符替換、字符刪除、字符串拆分等。在實際應(yīng)用中,網(wǎng)頁文檔結(jié)構(gòu)不完整,甚至結(jié)構(gòu)錯誤是常有的,平時之所以不明顯,是因為瀏覽器有一定的容錯能力。但R軟件中的網(wǎng)頁解析器卻沒有這樣的功能,在這種情況下就可以使用正則表達式來處理網(wǎng)頁內(nèi)容。
(6)Xpath工具
Xpath是XML文檔路徑語言。其抓取數(shù)據(jù)的細節(jié)與正則表達式相似,但Xpath是建立在文檔的結(jié)構(gòu)性的基礎(chǔ)上的,可以理解為:Xpath通過網(wǎng)絡(luò)文檔的結(jié)構(gòu)描述目標(biāo)的“地址”。關(guān)于Xpath的具體方法有很多,常用的是絕對路徑、相對路徑和謂語。絕對路徑,是按照結(jié)構(gòu)層次一層不落的索引到目標(biāo)標(biāo)簽上的;而相對路徑,則是缺省了某個或某些層次,一般用“//”或“/*/”符號代替。相對路徑因為有缺省,故而可能有多個節(jié)點滿足,則Xpath會同時定位到多個節(jié)點上。使用絕對路徑相對有個優(yōu)點就是返回結(jié)果是唯一的,當(dāng)定位成功后查找便終止;而相對路徑書寫輕松,卻會遍歷整個DOM樹。
(1)操作URL訪問多個界面
這是R軟件進行網(wǎng)絡(luò)數(shù)據(jù)搜集的主要應(yīng)用場景。批量下載數(shù)據(jù)是一種重復(fù)性的工作,往往是對多個界面中某些有規(guī)律信息的下載。操作者可以通過觀察URL規(guī)律,手動構(gòu)造URL進行數(shù)據(jù)訪問。例如,很多URL,都有“page=xxxx”這樣的形式,通過提交page參數(shù)來決定URL返回到某頁。又例如,很多新聞網(wǎng)站,都有著“/2016/”“/2017/”這些有規(guī)律的字樣。這些都是URL提交的參數(shù),用以返回特定的搜索結(jié)果。而理解這樣的參數(shù)并不難??梢哉业竭@樣的規(guī)律,通過stringr包的幫助,手動構(gòu)建URL集合,實現(xiàn)對多個界面的訪問。
(2)動態(tài)網(wǎng)頁和RSelenium包
很多網(wǎng)頁應(yīng)用了動態(tài)頁面技術(shù),即AJAX技術(shù)。AJAX即異步JavaScript和XML,是一種動態(tài)網(wǎng)站的構(gòu)建技術(shù),即使用JavaScript控制,可以只更新網(wǎng)頁部分內(nèi)容的一種技術(shù)。在網(wǎng)頁數(shù)據(jù)搜集的工作中,這門技術(shù)給設(shè)置的障礙最大的地方常常是翻頁和頁面滾動等。例如一些購物網(wǎng)站的商品評價,翻頁之后,內(nèi)容改變了,URL卻是不改變。又如部分網(wǎng)站剛剛打開界面時頁面是不全的,之后把頁面下拉至底部的時候,其余部分才會加載。
對于翻頁問題,有兩個常用方法。由于動態(tài)網(wǎng)頁是有數(shù)據(jù)庫支持的,故而可通過查看JavaScript代碼找到數(shù)據(jù)庫,直接訪問數(shù)據(jù)庫。另一個方法是模擬瀏覽器的方法。第一個方法的可行性不高,幾乎沒有任何正規(guī)網(wǎng)站會愿意讓訪客直接訪問其數(shù)據(jù)庫。相對而言,第二個方法比較簡單可行。
而使用第二種方法工作,需要下載Selenium軟件。Selenium服務(wù)器是用于測試瀏覽器①一般,Selenium只能用于檢測Firefox,chrome,IE等部分瀏覽器,而非全部。的。它的測試方式是通過JavaScript模擬真實用戶對瀏覽器進行操作。而這個特性,正好滿足第二種方法的需求。只要利用R調(diào)用Selenium服務(wù)器,便可以間接控制瀏覽器,模擬真實用戶運行瀏覽器。RSelenium軟件包會幫助操作者實現(xiàn)對Selenium軟件的調(diào)用。
當(dāng)R代碼運行的時候,瀏覽器會如同有人操作一般自動彈出一個新窗口,并跟隨代碼命令而動。如果同時打開命令界面,可以看到命令界面工作的過程。這種模擬瀏覽器的方式的特點是方便,它也可用于操作靜態(tài)頁面。但是靜態(tài)頁面是不建議這樣做的,因為這種操作方式的速度較慢。
API的全稱為應(yīng)用程序編程接口,是有些平臺如新浪微博、推特等,用于方便程序員搭建應(yīng)用時從平臺獲取數(shù)據(jù)。API有兩個標(biāo)準,一個是表征狀態(tài)轉(zhuǎn)移REST和簡單對象訪問協(xié)議SOAP。現(xiàn)在一般是使用REST。其中,表征文檔是HTML、XML、JSON等實際存儲數(shù)據(jù)的文檔,而交流的方式和網(wǎng)頁交流的方式一樣,一般為GET或POST。簡單的說,就是通過GET或POST(有時還有PUT和DELECT)這樣的方式,來交換數(shù)據(jù)信息。而這樣的數(shù)據(jù)信息,存在于各表征文檔中。
通過API訪問網(wǎng)站數(shù)據(jù)可以分為無需密碼的API訪問和需要身份驗證的API訪問。無需密碼的API訪問:對于一個REST式API的GET請求,和網(wǎng)頁的GET請求的不同之處,在于API響應(yīng)的只有數(shù)據(jù)文檔內(nèi)容。對于API得到的文件,可以由其具體的形式確定處理辦法。目前,JSON文檔成為了API中信息的主流存儲模式。只要訪問API成功,剩下的工作就視其文檔類型而定。有些時候,API獲取信息會遇到身份驗證,這就是OAuth身份驗證。訪問者需提供消費者密鑰,用以限制權(quán)限,訪問量以及追蹤數(shù)據(jù)。OAuth是個重要的授權(quán)標(biāo)準,例如新浪微博API就采取了OAuth驗證。為了獲取API的OAuth,操作者可以事先申請一個應(yīng)用,通過這個應(yīng)用申請OAuth密鑰。這是一個比較直接的方法。R包“httr”中有一套組件是用于OAuth證書申請的。利用這些函數(shù),可以進行OAuth驗證的相關(guān)操作。
(1)下載鏈接中現(xiàn)成可閱的文件
有些重要的數(shù)據(jù),網(wǎng)站會提供鏈接以供下載,下載后便是例如PDF、csv等可閱讀的文件。R參與這種情景,往往是因為鏈接很多或分布在各個界面。XML包里有一個合適的工作函數(shù)即getHTMLLinks(),可以用來在HTML網(wǎng)頁里識別鏈接。通過這個函數(shù),便可利用R中的download.file()或者getBinaryURL()(試用二進制數(shù)據(jù),例如PDF,圖片等)進行下載。操作者還可以使用FTP協(xié)議。利用FTP進行文件下載,會自動的略去HTML的布局等無關(guān)信息。同樣,F(xiàn)TP協(xié)議下的網(wǎng)頁也可以直接使用getURL函數(shù)訪問。
(2)從HTML網(wǎng)頁采集列表、表格信息及其他信息
R軟件搜集位于網(wǎng)頁源代碼中的數(shù)據(jù),往往是有價值,因此,專業(yè)的網(wǎng)站設(shè)計者也會用列表、表格等清晰的展現(xiàn)形式。所以,下載網(wǎng)頁中的表格是十分常見的工作,故而R中有一套專門采集這些信息的組件、函數(shù)。XML包中有著readHTMLLis(t)函數(shù)和getHTMLTable()函數(shù),它們分別可用于鏈接獲取和表格獲取。
不過,在同一個網(wǎng)頁中,列表或者表格多達到數(shù)十個甚是數(shù)百個是很正常的,而且,很多表格沒有名稱,所以Xpath對所在表格進行定位是很必要的。Xpath路徑可以通過參數(shù)的傳遞被函數(shù)所使用,從而對象(表格、列表、鏈接)獲取固定在某個子范圍內(nèi)。當(dāng)有些信息不存在與表格或列表中,可以按照前文HTML文檔處理的方式進行搜集。
(3)處理HTML表單
有時信息需要通過站內(nèi)搜索或者全網(wǎng)搜索來獲取。這就是HTML表單的處理。表單對話的方式很多,但是可以這樣簡單的理解:訪問者提交某些參數(shù),服務(wù)器篩選后返回符合這些參數(shù)的結(jié)果集合給訪問者。只不過,常用的提交方法GET和POST的區(qū)別在于,GET提交方法中,參數(shù)被用于組合成一定形式的URL,而POST提交方法中這些參數(shù)是通過正文發(fā)送而已。所要做的,找到表單(即找到表單的節(jié)點標(biāo)簽