开源 Python网络爬虫框架 Scrapy
?
開源 Python 網絡爬蟲框架 Scrapy:http://blog.csdn.net/zbyufei/article/details/7554322
?
?
介紹
?
所謂網絡爬蟲,就是一個在網上到處或定向抓取數據的程序,當然,這種說法不夠專業,更專業的描述就是,抓取特定網站網頁的HTML數據。不過由于一個網站的網頁很多,而我們又不可能事先知道所有網頁的URL地址,所以,如何保證我們抓取到了網站的所有HTML頁面就是一個有待考究的問題了。
一般的方法是,定義一個入口頁面,然后一般一個頁面會有其他頁面的URL,于是從當前頁面獲取到這些URL加入到爬蟲的抓取隊列中,然后進入到新新頁面后再遞歸的進行上述的操作,其實說來就跟深度遍歷或廣度遍歷一樣。
上面介紹的只是爬蟲的一些概念而非搜索引擎,實際上搜索引擎的話其系統是相當復雜的,爬蟲只是搜索引擎的一個子系統而已。
?
下面介紹一個開源的爬蟲框架 Scrapy。
?
?
一、概述
?
Scrapy是一個用?Python?寫的 Crawler Framework ,簡單輕巧,并且非常方便,并且官網上說已經在實際生產中在使用了,不過現在還沒有 Release 版本,可以直接使用他們的 Mercurial 倉庫里抓取源碼進行安裝。
Scrapy 使用 Twisted 這個異步網絡庫來處理網絡通訊,架構清晰,并且包含了各種中間件接口,可以靈活的完成各種需求。整體架構如下圖所示:
綠線是數據流向,首先從初始 URL 開始,Scheduler 會將其交給 Downloader 進行下載,下載之后會交給 Spider 進行分析,Spider 分析出來的結果有兩種:一種是需要進一步抓取的鏈接,例如之前分析的“下一頁”的鏈接,這些東西會被傳回 Scheduler ;另一種是需要保存的數據,它們則被送到 Item Pipeline 那里,那是對數據進行后期處理(詳細分析、過濾、存儲等)的地方。另外,在數據流動的通道里還可以安裝各種中間件,進行必要的處理。
?
?
二、組件
?
scrapy 組件
- 1、Scrapy Engine(Scrapy引擎):Scrapy引擎是用來控制整個系統的數據處理流程,并進行事務處理的觸發。更多的詳細內容可以看下面的數據處理流程。
- 2、Scheduler(調度器):調度程序從Scrapy引擎接受請求并排序列入隊列,并在Scrapy引擎發出請求后返還給他們。
- 3、Downloader(下載器):下載器的主要職責是抓取網頁并將網頁內容返還給蜘蛛( Spiders)。
- 4、Spiders(蜘蛛):蜘蛛是有Scrapy用戶自己定義用來解析網頁并抓取制定URL返回的內容的類,每個蜘蛛都能處理一個域名或一組域名。換句話說就是用來定義特定網站的抓取和解析規則。
? ? ? ? ?Spiders ( 蜘蛛?)?的整個抓取流程(周期)是這樣的:
- 5、Item Pipeline(項目管道):項目管道的主要責任是負責處理有蜘蛛從網頁中抽取的項目,他的主要任務是清晰、驗證和存儲數據。當頁面被蜘蛛解析后,將被發送到項目管道,并經過幾個特定的次序處理數據。每個項目管道的組件都是有一個簡單的方法組成的Python類。他們獲取了項目并執行他們的方法,同時他們還需要確定的是是否需要在項目管道中繼續執行下一步或是直接丟棄掉不處理。
? ? ? ? 項目管道通常執行的過程有:
- 6、Downloader middlewares(下載器中間件):?下載中間件是位于Scrapy引擎和下載器之間的鉤子框架,主要是處理Scrapy引擎與下載器之間的請求及響應。它提供了一個自定義的代碼的方式來拓展Scrapy的功能。下載中間器是一個處理請求和響應的鉤子框架。他是輕量級的,對Scrapy盡享全局控制的底層的系統。
- 7、Spider middlewares(蜘蛛中間件):蜘蛛中間件是介于Scrapy引擎和蜘蛛之間的鉤子框架,主要工作是處理蜘蛛的響應輸入和請求輸出。它提供一個自定義代碼的方式來拓展Scrapy的功能。蛛中間件是一個掛接到Scrapy的蜘蛛處理機制的框架,你可以插入自定義的代碼來處理發送給蜘蛛的請求和返回蜘蛛獲取的響應內容和項目。
- 8、Scheduler middlewares(調度中間件):調度中間件是介于Scrapy引擎和調度之間的中間件,主要工作是處從Scrapy引擎發送到調度的請求和響應。他提供了一個自定義的代碼來拓展Scrapy的功能。
?
?
三、數據處理流程
?
Scrapy的整個數據處理流程有Scrapy引擎進行控制,其主要的運行方式為:
?
?
四、安裝:
?
Scrapy是一個快速,高層次的屏幕抓取和web抓取框架,用于抓取web站點并從頁面中提取結構化的數據。Scrapy用途廣泛,可以用于數據挖掘、監測和自動化測試。Scrapy吸引人的地方在于它是一個框架,任何人都可以根據需求方便的修改。它也提供了多種類型爬蟲的基類,如BaseSpider、sitemap爬蟲等,最新版本又提供了web2.0爬蟲的支持。
?
下面介紹Scrapy在windows下的安裝:
首先下載windows版:Scrapy-0.15.0.2842.win32.exe,直接安裝。
安裝之后不能直接運行scrapy提供的test,會提示錯誤,因為scrapy基于其他一些python庫,需要把這些庫都安裝才行。
Twisted:Twisted Matrix 是一種用來進行網絡服務和應用程序編程的純 Python 框架,雖然 Twisted Matrix 中有大量松散耦合的模塊化組件,但該框架的中心概念還是非阻塞異步服務器這一思想。Twisted的安裝也非常簡單,在這里直接下載windows平臺下的相應版本即可:http://pypi.python.org/packages/2.7/T/Twisted/,
zope.interface:在這里下載http://pypi.python.org/pypi/zope.interface/3.8.0#downloads。zope.interface沒有提供windows平臺下的exe版,只提供了windows平臺下的egg包。
ez_setup:下載http://pypi.python.org/pypi/ez_setup,安裝。將egg文件放置在{python安裝目錄}\Scripts目錄下。
打開CMD并切換至scripts目錄,easy_install zope.interface-3.8.0-py2.6-win32.egg安裝。
w3lib:zope.interface問題解決之后還會提示缺少w3lib,下載http://pypi.python.org/pypi/w3lib后安裝即可
libxml2:使用scrapy的html解析功能時,會提示你缺少libxml2,所以我們先把這個也裝上,地址http://xmlsoft.org/sources/win32/python/,下載相應的版本即可。
至此就可以使用Scrapy玩spider了,大家可以根據文檔寫一個簡單的爬蟲試試,實際上使用scrapy做一個簡易的爬蟲甚至只需要幾行代碼就可以了,以后有空再詳細說說使用方法,本文不做更多描述。
?
?
五、入門
?
本文參考Scrapy Tutorial里面的文檔,翻譯出來加上自己的理解,供大家學習。
在本文中,我們將學會如何使用Scrapy建立一個爬蟲程序,并爬取指定網站上的內容,這一切在Scrapy框架內實現將是很簡單輕松的事情。
本教程主要內容包括一下四步:
- 1.?創建一個新的Scrapy Project
- 2.?定義你需要從網頁中提取的元素Item
- 3.?實現一個Spider類,通過接口完成爬取URL和提取Item的功能
- 4.?實現一個Item PipeLine類,完成Item的存儲功能
?
新建工程
首先,為我們的爬蟲新建一個工程,首先進入一個目錄(任意一個我們用來保存代碼的目錄),執行:
scrapy startproject Domz最后的Domz就是項目名稱。這個命令會在當前目錄下創建一個新目錄Domz,結構如下:
dmoz/ scrapy.cfg dmoz/ __init__.py items.py pipelines.py settings.py spiders/ __init__.pyscrapy.cfg: 項目配置文件
items.py: 需要提取的數據結構定義文件
pipelines.py: 管道定義,用來對items里面提取的數據做進一步處理,如保存等
settings.py: 爬蟲配置文件
spiders: 放置spider的目錄
?
定義Item
在items.py里面定義我們要抓取的數據:
from scrapy.item import Item, Field class DmozItem(Item): title = Field() link = Field() desc = Field()這里我們需要獲取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:
class DmozSpider(BaseSpider): name = "dmoz.org" start_urls = [ "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/", "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/" ] def parse(self, response): filename = response.url.split("/")[-2] open(filename, 'wb').write(response.body)?
提取Item
提取數據到Items里面,主要用到XPath提取網頁數據:
scrapy有提供兩個XPath選擇器,HtmlXPathSelector和XmlXPathSelector,一個用于HTML,一個用于XML,XPath選擇器有三個方法
select(xpath): 返回一個相對于當前選中節點的選擇器列表(一個XPath可能選到多個節點)
extract(): 返回選擇器(列表)對應的節點的字符串(列表)
re(regex): 返回正則表達式匹配的字符串(分組匹配)列表
一種很好的方法是在Shell里面對XPath進行測試:
現在修改parse()方法看看如何提取數據到items里面去:
def parse(self, response): hxs = HtmlXPathSelector(response) sites = hxs.select('//ul/li') items = [] for site in sites: item = DmozItem() item['title'] = site.select('a/text()').extract() item['link'] = site.select('a/@href').extract() item['desc'] = site.select('text()').extract() items.append(item) return items?
實現PipeLine
PipeLine用來對Spider返回的Item列表進行保存操作,可以寫入到文件、或者數據庫等。
PipeLine只有一個需要實現的方法:process_item,例如我們將Item保存到一個文件中:
def __init__(self): self.file = open('jingdong.txt', 'wb') def process_item(self, item, spider): self.file.write(item['title'] + '\t'+ item['link'] + '\t' + item['desc']+'\n')到現在,我們就完成了一個基本的爬蟲的實現,可以輸入下面的命令來啟動這個Spider:
scrapy crawl dmoz.org?
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()方法代碼如下:
from scrapy.selector import HtmlXPathSelector def parse(self, response): hxs = HtmlXPathSelector(response) items = [] newurls = hxs.select('//a/@href').extract() validurls = [] for url in newurls: #判斷URL是否合法 if true: validurls.append(url) items.extend([self.make_requests_from_url(url).replace(callback=self.parse) for url in validurls]) sites = hxs.select('//ul/li') items = [] for site in sites: item = DmozItem() item['title'] = site.select('a/text()').extract() item['link'] = site.select('a/@href').extract() item['desc'] = site.select('text()').extract() items.append(item) return items?
?
?
?
?
總結
以上是生活随笔為你收集整理的开源 Python网络爬虫框架 Scrapy的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 异步 IO 、协程、asy
- 下一篇: 用 Python 和 werobot 框