介紹:
所謂網絡爬蟲,就是一個在網上到處或定向抓取資料的程式,當然,這種說法不夠專業,更專業的描述就是,抓取特定網站網頁的html資料。不過由于一個網站的網頁很多,而我們又不可能事先知道所有網頁的url位址,是以,如何保證我們抓取到了網站的所有html頁面就是一個有待考究的問題了。
一般的方法是,定義一個入口頁面,然後一般一個頁面會有其他頁面的url,于是從目前頁面擷取到這些url加入到爬蟲的抓取隊列中,然後進入到新新頁面後再遞歸的進行上述的操作,其實說來就跟深度周遊或廣度周遊一樣。
上面介紹的隻是爬蟲的一些概念而非搜尋引擎,實際上搜尋引擎的話其系統是相當複雜的,爬蟲隻是搜尋引擎的一個子系統而已。下面介紹一個開源的爬蟲架構scrapy。
一、概述
release 版本,可以直接使用他們的 mercurial 倉庫裡抓取源碼進行安裝。

綠線是資料流向,首先從初始 url 開始,scheduler 會将其交給 downloader 進行下載下傳,下載下傳之後會交給 spider 進行分析,spider 分析出來的結果有兩種:一種是需要進一步抓取的連結,例如之前分析的“下一頁”的連結,這些東西會被傳回 scheduler ;另一種是需要儲存的資料,它們則被送到 item pipeline 那裡,那是對資料進行後期處理(詳細分析、過濾、存儲等)的地方。另外,在資料流動的通道裡還可以安裝各種中間件,進行必要的處理。
二、元件
1、scrapy engine(scrapy引擎)
scrapy引擎是用來控制整個系統的資料處理流程,并進行事務處理的觸發。更多的詳細内容可以看下面的資料處理流程。
2、scheduler(排程)
排程程式從scrapy引擎接受請求并排序列入隊列,并在scrapy引擎送出請求後返還給他們。
3、downloader(下載下傳器)
下載下傳器的主要職責是抓取網頁并将網頁内容返還給蜘蛛( spiders)。
4、spiders(蜘蛛)
蜘蛛是有scrapy使用者自己定義用來解析網頁并抓取制定url傳回的内容的類,每個蜘蛛都能處理一個域名或一組域名。換句話說就是用來定義特定網站的抓取和解析規則。
蜘蛛的整個抓取流程(周期)是這樣的:
首先擷取第一個url的初始請求,當請求傳回後調取一個回調函數。第一個請求是通過調用start_requests()方法。該方法預設從start_urls中的url中生成請求,并執行解析來調用回調函數。
在回調函數中,你可以解析網頁響應并傳回項目對象和請求對象或兩者的疊代。這些請求也将包含一個回調,然後被scrapy下載下傳,然後有指定的回調處理。
在回調函數中,你解析網站的内容,同程使用的是xpath選擇器(但是你也可以使用beautifusoup, lxml或其他任何你喜歡的程式),并生成解析的資料項。
最後,從蜘蛛傳回的項目通常會進駐到項目管道。
5、item pipeline(項目管道)
項目管道的主要責任是負責處理有蜘蛛從網頁中抽取的項目,他的主要任務是清晰、驗證和存儲資料。當頁面被蜘蛛解析後,将被發送到項目管道,并經過幾個特定的次序處理資料。每個項目管道的元件都是有一個簡單的方法組成的python類。他們擷取了項目并執行他們的方法,同時他們還需要确定的是是否需要在項目管道中繼續執行下一步或是直接丢棄掉不處理。
項目管道通常執行的過程有:
清洗html資料
驗證解析到的資料(檢查項目是否包含必要的字段)
檢查是否是重複資料(如果重複就删除)
将解析到的資料存儲到資料庫中
6、downloader middlewares(下載下傳器中間件)
下載下傳中間件是位于scrapy引擎和下載下傳器之間的鈎子架構,主要是處理scrapy引擎與下載下傳器之間的請求及響應。它提供了一個自定義的代碼的方式來拓展scrapy的功能。下載下傳中間器是一個處理請求和響應的鈎子架構。他是輕量級的,對scrapy盡享全局控制的底層的系統。
7、spider middlewares(蜘蛛中間件)
蜘蛛中間件是介于scrapy引擎和蜘蛛之間的鈎子架構,主要工作是處理蜘蛛的響應輸入和請求輸出。它提供一個自定義代碼的方式來拓展scrapy的功能。蛛中間件是一個挂接到scrapy的蜘蛛處理機制的架構,你可以插入自定義的代碼來處理發送給蜘蛛的請求和傳回蜘蛛擷取的響應内容和項目。
8、scheduler middlewares(排程中間件)
排程中間件是介于scrapy引擎和排程之間的中間件,主要工作是處從scrapy引擎發送到排程的請求和響應。他提供了一個自定義的代碼來拓展scrapy的功能。
三、資料處理流程
scrapy的整個資料處理流程有scrapy引擎進行控制,其主要的運作方式為:
引擎打開一個域名,時蜘蛛處理這個域名,并讓蜘蛛擷取第一個爬取的url。
引擎從蜘蛛那擷取第一個需要爬取的url,然後作為請求在排程中進行排程。
引擎從排程那擷取接下來進行爬取的頁面。
排程将下一個爬取的url傳回給引擎,引擎将他們通過下載下傳中間件發送到下載下傳器。
當網頁被下載下傳器下載下傳完成以後,響應内容通過下載下傳中間件被發送到引擎。
引擎收到下載下傳器的響應并将它通過蜘蛛中間件發送到蜘蛛進行處理。
蜘蛛處理響應并傳回爬取到的項目,然後給引擎發送新的請求。
引擎将抓取到的項目項目管道,并向排程發送請求。
系統重複第二部後面的操作,直到排程中沒有請求,然後斷開引擎與域之間的聯系。
安裝:
scrapy是一個快速,高層次的螢幕抓取和web抓取架構,用于抓取web站點并從頁面中提取結構化的資料。scrapy用途廣泛,可以用于資料挖掘、監測和自動化測試。scrapy吸引人的地方在于它是一個架構,任何人都可以根據需求友善的修改。它也提供了多種類型爬蟲的基類,如basespider、sitemap爬蟲等,最新版本又提供了web2.0爬蟲的支援。
下面介紹scrapy在windows下的安裝:
安裝之後不能直接運作scrapy提供的test,會提示錯誤,因為scrapy基于其他一些python庫,需要把這些庫都安裝才行。
打開cmd并切換至scripts目錄,easy_install zope.interface-3.8.0-py2.6-win32.egg安裝。
至此就可以使用scrapy玩spider了,大家可以根據文檔寫一個簡單的爬蟲試試,實際上使用scrapy做一個簡易的爬蟲甚至隻需要幾行代碼就可以了,以後有空再詳細說說使用方法,本文不做更多描述。
入門:
本文參考scrapy tutorial裡面的文檔,翻譯出來加上自己的了解,供大家學習。
在本文中,我們将學會如何使用scrapy建立一個爬蟲程式,并爬取指定網站上的内容,這一切在scrapy架構内實作将是很簡單輕松的事情。
本教程主要内容包括一下四步:
1. 建立一個新的scrapy project
2. 定義你需要從網頁中提取的元素item
3. 實作一個spider類,通過接口完成爬取url和提取item的功能
4. 實作一個item pipeline類,完成item的存儲功能
建立工程
首先,為我們的爬蟲建立一個工程,首先進入一個目錄(任意一個我們用來儲存代碼的目錄),執行:
最後的domz就是項目名稱。這個指令會在目前目錄下建立一個新目錄domz,結構如下:
scrapy.cfg: 項目配置檔案
pipelines.py: 管道定義,用來對items裡面提取的資料做進一步處理,如儲存等
settings.py: 爬蟲配置檔案
spiders: 放置spider的目錄
定義item
在items.py裡面定義我們要抓取的資料:
這裡我們需要擷取dmoz頁面上的标題,連結,描述,是以定義一個對應的items結構,不像django裡面models的定義有那麼多種類的field,這裡隻有一種就叫field(),再複雜就是field可以接受一個default值。
實作spider
spider隻是一個繼承字scrapy.spider.basespider的python類,有三個必需的定義的成員
name: 名字,這個spider的辨別
start_urls: 一個url清單,spider從這些網頁開始抓取
parse(): 一個方法,當start_urls裡面的網頁抓取下來之後需要調用這個方法解析網頁内容,同時需要傳回下一個需要抓取的網頁,或者傳回items清單
是以在spiders目錄下建立一個spider,dmoz_spider.py:
提取item
提取資料到items裡面,主要用到xpath提取網頁資料:
scrapy有提供兩個xpath選擇器,htmlxpathselector和xmlxpathselector,一個用于html,一個用于xml,xpath選擇器有三個方法
select(xpath): 傳回一個相對于目前選中節點的選擇器清單(一個xpath可能選到多個節點)
extract(): 傳回選擇器(清單)對應的節點的字元串(清單)
re(regex): 傳回正規表達式比對的字元串(分組比對)清單
一種很好的方法是在shell裡面對xpath進行測試:
現在修改parse()方法看看如何提取資料到items裡面去:
實作pipeline
pipeline隻有一個需要實作的方法:process_item,例如我們将item儲存到一個檔案中:
到現在,我們就完成了一個基本的爬蟲的實作,可以輸入下面的指令來啟動這個spider:
scrapy之url解析與遞歸爬取:
前面介紹了scrapy如何實作一個最簡單的爬蟲,但是這個demo裡隻是對一個頁面進行了抓取。在實際應用中,爬蟲一個重要功能是”發現新頁面”,然後遞歸的讓爬取操作進行下去。
發現新頁面的方法很簡單,我們首先定義一個爬蟲的入口url位址,比如scrapy入門教程中的start_urls,爬蟲首先将這個頁面的内容抓取之後,解析其内容,将所有的連結位址提取出來。這個提取的過程是很簡單的,通過一個html解析庫,将這樣的節點内容提取出來,href參數的值就是一個新頁面的url。擷取這個url值之後,将其加入到任務隊列中,爬蟲不斷的從隊列中取url即可。這樣,隻需要為爬蟲定義一個入口的url,那麼爬蟲就能夠自動的爬取到指定網站的絕大多數頁面。
當然,在具體的實作中,我們還需要對提取的url做進一步處理:
1. 判斷url指向網站的域名,如果指向的是外部網站,那麼可以将其丢棄
2. url去重,可以将所有爬取過的url存入資料庫中,然後查詢新提取的url在資料庫中是否存在,如果存在的話,當然就無需再去爬取了。
下面介紹一下如何在scrapy中完成上述這樣的功能。
我們隻需要改寫spider的那個py檔案即可,修改parse()方法代碼如下: