齊 鵬,李隱峰,宋玉偉
(西安電子科技大學(xué)電子工程學(xué)院,陜西西安 710126)
Web數(shù)據(jù)抓取(Web Scraping)是指從網(wǎng)站上提取信息的一種計算機軟件技術(shù)。Web數(shù)據(jù)抓取程序模擬瀏覽器的行為,能將任何可以在瀏覽器上顯示的數(shù)據(jù)提取出來,因此也稱為屏幕抓取(Screen Scraping)。Web數(shù)據(jù)抓取的最終目的是將非結(jié)構(gòu)化的信息從大量的網(wǎng)頁中抽取出來以結(jié)構(gòu)化的方式存儲(CSV、JSON、XML、Access、Mssql、Mysql等)。簡而言之,Web 數(shù)據(jù)采集就是從指定網(wǎng)站抓取所需的非結(jié)構(gòu)化信息數(shù)據(jù),分析處理后存儲為統(tǒng)一格式的本地數(shù)據(jù)文件或直接存入本地數(shù)據(jù)庫中。
Internet是一個巨大的且迅速發(fā)展的信息資源。但大多數(shù)信息都以無結(jié)構(gòu)的文本形式存在,使得信息歸類變得非常困難。在Web Scraping出現(xiàn)之前,人們?yōu)榱藲w類數(shù)據(jù)通常會采用手動復(fù)制粘貼的方式,這樣不但費時費力,而且數(shù)據(jù)質(zhì)量得不到保證,效率低。有時遇到海量數(shù)據(jù)的時候,靠人工整理甚至是無法完成。Web Scraping是一個使用計算機程序自動從目標(biāo)網(wǎng)頁中摘取某些數(shù)據(jù)形成統(tǒng)一格式的本地數(shù)據(jù)的過程,整個過程基本不需要人工干預(yù)。其效率較高:
(1)速度快。抓取程序的數(shù)據(jù)加載速度要比瀏覽器快,因為通常情況下瀏覽器不但要下載基本的HTML數(shù)據(jù)還需要下載相關(guān)的樣式表、Java Script文件、多媒體資源,還要由渲染引擎進行頁面排版布局,Java Script引擎還要進行客戶端代碼執(zhí)行。而抓取程序只需要下載基本的HTML數(shù)據(jù)即可,這樣可縮短數(shù)據(jù)下載時間。另外,程序的數(shù)據(jù)提取速度會比人工復(fù)制粘貼速度快得多,再結(jié)合多線程技術(shù),速度更是人工所無法比擬的。
(2)準(zhǔn)確性高。人工操作會產(chǎn)生信息遺漏或錯誤的情況,而且糾錯難度大。而程序的準(zhǔn)確性較高,即便出現(xiàn)問題,糾錯也容易,通常只需要修改程序即可。
Web Scraping程序在計算機網(wǎng)絡(luò)通信的傳輸層,使用TCP協(xié)議與Web服務(wù)器進行數(shù)據(jù)傳輸,在應(yīng)用層使用HTTP協(xié)議與服務(wù)器進行數(shù)據(jù)交互。它與服務(wù)器的通信過程和HTTP客戶端程序瀏覽器一致。
Web Scraping程序從功能上可以劃分為兩大模塊:HTTP交互模塊和HTML解析模塊。對一個網(wǎng)頁的抓取過程是:首先HTTP交互模塊向服務(wù)器的Web端口發(fā)起TCP連接,連接建立后,交互模塊即可向Web服務(wù)器發(fā)送HTP請求報文,當(dāng)HTTP交互模塊接收到服務(wù)端的應(yīng)答報文后,進行HTTP包拆封,提取其中的HTML數(shù)據(jù),然后將數(shù)據(jù)交由HTML解析模塊進行數(shù)據(jù)解析和提取,最后解析模塊將提取的數(shù)據(jù)以格式化的形式存儲于數(shù)據(jù)庫系統(tǒng)或者是簡單的結(jié)構(gòu)化的文本文件(CSV、TSV、XML等)。整個流程如圖 1所示。
圖1 Web Scraping的原理
Web Scraping程序?qū)σ粋€網(wǎng)站的采集過程就是分別對網(wǎng)站內(nèi)感興趣的每個頁面采集的集合。為得到網(wǎng)站所需要采集的頁面地址,需要首選對網(wǎng)站的結(jié)構(gòu)進行分析,總結(jié)出頁面的規(guī)律,例如,網(wǎng)站通常會有一些信息集中的列表頁,通過遍歷這些列表頁即可得到所有詳細頁面的地址。
對于某些網(wǎng)站在于服務(wù)器交互的過程中可能會用到Cookie,這時就需要抓取程序還能夠?qū)TTP報文中的Cookie進行管理,例如,當(dāng)服務(wù)端的應(yīng)答報文中含有Set-cookie字段時,要提取Cookie數(shù)據(jù)并在客戶端存儲或更新;之后發(fā)送請求報文時,要將Cookie一并發(fā)回服務(wù)端。
HTML解析模塊負責(zé)對HTML數(shù)據(jù)進行提取和規(guī)范化處理,然后將數(shù)據(jù)以結(jié)構(gòu)化的形式存儲。
Python是一種面向?qū)ο蟆⒅弊g式計算機程序設(shè)計語言。其語法簡捷而清晰、可讀性強、便于維護,并且具有豐富和強大的類庫[1]。為Web Scraping程序開發(fā)提供了便利:可以使用HTTP通信模塊urllib2完成與Web服務(wù)器的數(shù)據(jù)交互,使用 cookielib模塊進行Cookie管理,使用re模塊進行文本提取[2],使用XPath相關(guān)庫進行HTML解析??傊?,Python提供了 Web Scraping程序的所有功能模塊,利用Python可以最少的代碼完成功能強大的功能。
Python的urllib2模塊包含于Python的標(biāo)準(zhǔn)庫中,它定義了一些類和方法主要用于實現(xiàn)對HTTP通信協(xié)議的支持。urllib2支持HTTP代理、HTTP簡單認證、跳轉(zhuǎn)、Cookie等功能[5]。urllib2模塊還支持對 HTTP請求報文的頭和實體進行增改,對HTTP應(yīng)答報文的頭和正文進行讀取。
如何利用urllib2模塊進行HTTP交互?urllib2.urlopen(url[,data][,timeout])方法提供了最基本的HTTP請求構(gòu)造和HTTP應(yīng)答處理功能。url參數(shù)指示了一個要下載的資源路徑。當(dāng)data參數(shù)為空時預(yù)示著將發(fā)出一個GET類型的請求,該請求不包含任何實體;當(dāng)data參數(shù)為非空時預(yù)示著將發(fā)出一個POST類型的請求,data的內(nèi)容即為請求的實體內(nèi)容。timeout參數(shù)指示了請求超時的時間。
urllib2.urlopen方法調(diào)用的結(jié)果有兩種情況:
(1)出現(xiàn)了HTTP錯誤。例如,網(wǎng)絡(luò)異常或Web服務(wù)異常造成的請求超時錯誤;服務(wù)端返回HTTP錯誤碼。這時urllib2.urlopen會拋出一個異常,可以通過捕獲不同的異常類型進而判斷錯誤的種類[5]。
(2)沒有出現(xiàn)HTTP錯誤。這時urllib2.urlopen返回一個類似文件的對象,通過調(diào)用該對象的read()方法可獲取到應(yīng)答返回的正文內(nèi)容(HTML)。如果返回是經(jīng)過gzip壓縮過的數(shù)據(jù),在這里還要手動進行g(shù)zip解碼。
cookielib模塊也包含于Python的標(biāo)準(zhǔn)庫中,它主要用于對Cookie進行管理[5],urllib2通過cookielib庫實現(xiàn)對Cookie自動維護。
通過HTML交互模塊可以取得網(wǎng)站頁面數(shù)據(jù),但是此時的數(shù)據(jù)粗糙,字符編碼不確定,結(jié)構(gòu)混亂甚至不符合XML規(guī)范。所以首先要確定文檔的字符編碼,通過<head>中的content-type元得到。然后將其解碼成unicode類型[3],目的是保證后續(xù)數(shù)據(jù)提取過程中的編碼一致性,以及最終數(shù)據(jù)存儲方便。
正則表達式:是指一個用來描述或者匹配一系列符合某個句法規(guī)則的字符串的工具。利用正則表達式可以方便地從一堆復(fù)雜的文本中找到與規(guī)則相匹配的子串,許多程序設(shè)計語言都支持利用正則表達式進行字符串操作。在Python標(biāo)準(zhǔn)庫中re是一個用來進行正則表達式相關(guān)操作的模塊[6]。通過對目標(biāo)頁面結(jié)構(gòu)進行分析,通常能夠在感興趣的字符串周圍找到其他有標(biāo)志性的字符,可以通過這些字符構(gòu)造出正則表達式,利用re模塊進行數(shù)據(jù)提取。
XPath:是一門在XML文檔中查找信息的語言,用于在XML文檔中通過元素和屬性進行導(dǎo)航。利用XPath可以方便地在HTML文檔中定位感興趣的節(jié)點。lxml庫是 Python的第三方庫,它支持標(biāo)準(zhǔn)的XPath 規(guī)范[7]。
通過正則表達式和XPath的結(jié)合就可靈活地從HTML中提取任何感興趣的信息。在提取到數(shù)據(jù)之后還要對其進行規(guī)范化處理,比如將HTML轉(zhuǎn)義字符進行反轉(zhuǎn)義、去除冗余的HTML標(biāo)記、去除冗余的空白字符。
結(jié)構(gòu)化數(shù)據(jù)通常指的是行數(shù)據(jù),存儲在數(shù)據(jù)庫里,可以用二維表結(jié)構(gòu)來邏輯表達實現(xiàn)的數(shù)據(jù)。Web Scraping程序最終輸出的數(shù)據(jù)是結(jié)構(gòu)化的,具體存儲于各種數(shù)據(jù)庫系統(tǒng)或文件中。在unicode數(shù)據(jù)進行本地化存儲之前必須要先進行字符編碼,具體的編碼方式可以根據(jù)需要選擇,一般是由數(shù)據(jù)最終的應(yīng)用環(huán)境決定的。比如,最終的數(shù)據(jù)將應(yīng)用在一個字符編碼為UTF-8的網(wǎng)站上,那么就要選擇以UTF-8的編碼進行存儲。
介紹了Web數(shù)據(jù)抓取技術(shù)以及其實現(xiàn)的原理,以及如何利用Python進行Web數(shù)據(jù)抓取程序的開發(fā)。Web數(shù)據(jù)抓取技術(shù)已在非結(jié)構(gòu)數(shù)據(jù)結(jié)構(gòu)化、Web程序自動化操作、定制搜索引擎爬蟲、輿情監(jiān)控等方面發(fā)揮重要作用。同時,為保護好自己的Web資源不被別人惡意采集,要做好應(yīng)對措施,限制網(wǎng)站單個IP的并發(fā)連接數(shù),可以使用Ajax動態(tài)加載網(wǎng)頁內(nèi)容或者將應(yīng)答內(nèi)容進行加密,將一些敏感的信息以非文本的形式展現(xiàn),都會給數(shù)據(jù)采集造成障礙。
[1]赫特蘭.Python基礎(chǔ)教程[M].2版.北京:人民郵電出版社,2010.
[2]丘恩.Python核心編程[M].2版.北京:人民郵電出版社,2008.
[3]魯特茲.Python學(xué)習(xí)手冊[M].北京:機械工業(yè)出版社,2009.
[4]桂小林,汪寧波,李文.基于XML的遠程教育課件規(guī)范化的研究與實現(xiàn)[J].電子科技,2010,23(6):129 -131.
[5]劉紅梅.腳本語言在數(shù)據(jù)采集系統(tǒng)中的應(yīng)用研究[J].電子科技,2009,22(11):72-75.