齊 鵬,李隱峰,宋玉偉
(西安電子科技大學電子工程學院,陜西西安 710126)
Web數據抓取(Web Scraping)是指從網站上提取信息的一種計算機軟件技術。Web數據抓取程序模擬瀏覽器的行為,能將任何可以在瀏覽器上顯示的數據提取出來,因此也稱為屏幕抓取(Screen Scraping)。Web數據抓取的最終目的是將非結構化的信息從大量的網頁中抽取出來以結構化的方式存儲(CSV、JSON、XML、Access、Mssql、Mysql等)。簡而言之,Web 數據采集就是從指定網站抓取所需的非結構化信息數據,分析處理后存儲為統一格式的本地數據文件或直接存入本地數據庫中。
Internet是一個巨大的且迅速發展的信息資源。但大多數信息都以無結構的文本形式存在,使得信息歸類變得非常困難。在Web Scraping出現之前,人們為了歸類數據通常會采用手動復制粘貼的方式,這樣不但費時費力,而且數據質量得不到保證,效率低。有時遇到海量數據的時候,靠人工整理甚至是無法完成。Web Scraping是一個使用計算機程序自動從目標網頁中摘取某些數據形成統一格式的本地數據的過程,整個過程基本不需要人工干預。其效率較高:
(1)速度快。抓取程序的數據加載速度要比瀏覽器快,因為通常情況下瀏覽器不但要下載基本的HTML數據還需要下載相關的樣式表、Java Script文件、多媒體資源,還要由渲染引擎進行頁面排版布局,Java Script引擎還要進行客戶端代碼執行。而抓取程序只需要下載基本的HTML數據即可,這樣可縮短數據下載時間。另外,程序的數據提取速度會比人工復制粘貼速度快得多,再結合多線程技術,速度更是人工所無法比擬的。
(2)準確性高。人工操作會產生信息遺漏或錯誤的情況,而且糾錯難度大。而程序的準確性較高,即便出現問題,糾錯也容易,通常只需要修改程序即可。
Web Scraping程序在計算機網絡通信的傳輸層,使用TCP協議與Web服務器進行數據傳輸,在應用層使用HTTP協議與服務器進行數據交互。它與服務器的通信過程和HTTP客戶端程序瀏覽器一致。
Web Scraping程序從功能上可以劃分為兩大模塊:HTTP交互模塊和HTML解析模塊。對一個網頁的抓取過程是:首先HTTP交互模塊向服務器的Web端口發起TCP連接,連接建立后,交互模塊即可向Web服務器發送HTP請求報文,當HTTP交互模塊接收到服務端的應答報文后,進行HTTP包拆封,提取其中的HTML數據,然后將數據交由HTML解析模塊進行數據解析和提取,最后解析模塊將提取的數據以格式化的形式存儲于數據庫系統或者是簡單的結構化的文本文件(CSV、TSV、XML等)。整個流程如圖 1所示。

圖1 Web Scraping的原理
Web Scraping程序對一個網站的采集過程就是分別對網站內感興趣的每個頁面采集的集合。為得到網站所需要采集的頁面地址,需要首選對網站的結構進行分析,總結出頁面的規律,例如,網站通常會有一些信息集中的列表頁,通過遍歷這些列表頁即可得到所有詳細頁面的地址。
對于某些網站在于服務器交互的過程中可能會用到Cookie,這時就需要抓取程序還能夠對HTTP報文中的Cookie進行管理,例如,當服務端的應答報文中含有Set-cookie字段時,要提取Cookie數據并在客戶端存儲或更新;之后發送請求報文時,要將Cookie一并發回服務端。
HTML解析模塊負責對HTML數據進行提取和規范化處理,然后將數據以結構化的形式存儲。
Python是一種面向對象、直譯式計算機程序設計語言。其語法簡捷而清晰、可讀性強、便于維護,并且具有豐富和強大的類庫[1]。為Web Scraping程序開發提供了便利:可以使用HTTP通信模塊urllib2完成與Web服務器的數據交互,使用 cookielib模塊進行Cookie管理,使用re模塊進行文本提取[2],使用XPath相關庫進行HTML解析。總之,Python提供了 Web Scraping程序的所有功能模塊,利用Python可以最少的代碼完成功能強大的功能。
Python的urllib2模塊包含于Python的標準庫中,它定義了一些類和方法主要用于實現對HTTP通信協議的支持。urllib2支持HTTP代理、HTTP簡單認證、跳轉、Cookie等功能[5]。urllib2模塊還支持對 HTTP請求報文的頭和實體進行增改,對HTTP應答報文的頭和正文進行讀取。
如何利用urllib2模塊進行HTTP交互?urllib2.urlopen(url[,data][,timeout])方法提供了最基本的HTTP請求構造和HTTP應答處理功能。url參數指示了一個要下載的資源路徑。當data參數為空時預示著將發出一個GET類型的請求,該請求不包含任何實體;當data參數為非空時預示著將發出一個POST類型的請求,data的內容即為請求的實體內容。timeout參數指示了請求超時的時間。
urllib2.urlopen方法調用的結果有兩種情況:
(1)出現了HTTP錯誤。例如,網絡異常或Web服務異常造成的請求超時錯誤;服務端返回HTTP錯誤碼。這時urllib2.urlopen會拋出一個異常,可以通過捕獲不同的異常類型進而判斷錯誤的種類[5]。
(2)沒有出現HTTP錯誤。這時urllib2.urlopen返回一個類似文件的對象,通過調用該對象的read()方法可獲取到應答返回的正文內容(HTML)。如果返回是經過gzip壓縮過的數據,在這里還要手動進行gzip解碼。
cookielib模塊也包含于Python的標準庫中,它主要用于對Cookie進行管理[5],urllib2通過cookielib庫實現對Cookie自動維護。
通過HTML交互模塊可以取得網站頁面數據,但是此時的數據粗糙,字符編碼不確定,結構混亂甚至不符合XML規范。所以首先要確定文檔的字符編碼,通過<head>中的content-type元得到。然后將其解碼成unicode類型[3],目的是保證后續數據提取過程中的編碼一致性,以及最終數據存儲方便。
正則表達式:是指一個用來描述或者匹配一系列符合某個句法規則的字符串的工具。利用正則表達式可以方便地從一堆復雜的文本中找到與規則相匹配的子串,許多程序設計語言都支持利用正則表達式進行字符串操作。在Python標準庫中re是一個用來進行正則表達式相關操作的模塊[6]。通過對目標頁面結構進行分析,通常能夠在感興趣的字符串周圍找到其他有標志性的字符,可以通過這些字符構造出正則表達式,利用re模塊進行數據提取。
XPath:是一門在XML文檔中查找信息的語言,用于在XML文檔中通過元素和屬性進行導航。利用XPath可以方便地在HTML文檔中定位感興趣的節點。lxml庫是 Python的第三方庫,它支持標準的XPath 規范[7]。
通過正則表達式和XPath的結合就可靈活地從HTML中提取任何感興趣的信息。在提取到數據之后還要對其進行規范化處理,比如將HTML轉義字符進行反轉義、去除冗余的HTML標記、去除冗余的空白字符。
結構化數據通常指的是行數據,存儲在數據庫里,可以用二維表結構來邏輯表達實現的數據。Web Scraping程序最終輸出的數據是結構化的,具體存儲于各種數據庫系統或文件中。在unicode數據進行本地化存儲之前必須要先進行字符編碼,具體的編碼方式可以根據需要選擇,一般是由數據最終的應用環境決定的。比如,最終的數據將應用在一個字符編碼為UTF-8的網站上,那么就要選擇以UTF-8的編碼進行存儲。
介紹了Web數據抓取技術以及其實現的原理,以及如何利用Python進行Web數據抓取程序的開發。Web數據抓取技術已在非結構數據結構化、Web程序自動化操作、定制搜索引擎爬蟲、輿情監控等方面發揮重要作用。同時,為保護好自己的Web資源不被別人惡意采集,要做好應對措施,限制網站單個IP的并發連接數,可以使用Ajax動態加載網頁內容或者將應答內容進行加密,將一些敏感的信息以非文本的形式展現,都會給數據采集造成障礙。
[1]赫特蘭.Python基礎教程[M].2版.北京:人民郵電出版社,2010.
[2]丘恩.Python核心編程[M].2版.北京:人民郵電出版社,2008.
[3]魯特茲.Python學習手冊[M].北京:機械工業出版社,2009.
[4]桂小林,汪寧波,李文.基于XML的遠程教育課件規范化的研究與實現[J].電子科技,2010,23(6):129 -131.
[5]劉紅梅.腳本語言在數據采集系統中的應用研究[J].電子科技,2009,22(11):72-75.