[轉載]學習Scrapy入門
作者:JasonDing
鏈接:【scrapy】學習Scrapy入門
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
原文地址:
【scrapy】學習Scrapy入門
也可參考:
Scrapy入門教程 - Scrapy 0.24.6 文檔Scrapy介紹
Scrapy是一個為了爬取網站數據,提取結構性數據而編寫的應用框架。 可以應用在包括數據挖掘,信息處理或存儲歷史數據等一系列的程序中。
所謂網路爬蟲,就是一個在網上到處或定向抓取數據的程序,當然,這種說法不夠專業,更專業的描述就是,抓取特定網站網頁的HTML數據。抓取網頁的一般方法是,定義一個入口頁面,然後一般一個頁面會有其他頁面的URL,於是從當前頁面獲取到這些URL加入到爬蟲的抓取隊列中,然後進入到新頁面後再遞歸的進行上述的操作,其實說來就跟深度遍歷或廣度遍歷一樣。Scrapy 使用 Twisted這個非同步網路庫來處理網路通訊,架構清晰,並且包含了各種中間件介面,可以靈活的完成各種需求。整體架構
- 引擎(Scrapy Engine),用來處理整個系統的數據流處理,觸發事務。
- 調度器(Scheduler),用來接受引擎發過來的請求,壓入隊列中,並在引擎再次請求的時候返回。
- 下載器(Downloader),用於下載網頁內容,並將網頁內容返回給蜘蛛。
- 蜘蛛(Spiders),蜘蛛是主要幹活的,用它來制訂特定域名或網頁的解析規則。編寫用於分析response並提取item(即獲取到的item)或額外跟進的URL的類。 每個spider負責處理一個特定(或一些)網站。
- 項目管道(Item Pipeline),負責處理有蜘蛛從網頁中抽取的項目,他的主要任務是清晰、驗證和存儲數據。當頁面被蜘蛛解析後,將被發送到項目管道,並經過幾個特定的次序處理數據。
- 下載器中間件(Downloader Middlewares),位於Scrapy引擎和下載器之間的鉤子框架,主要是處理Scrapy引擎與下載器之間的請求及響應。
- 蜘蛛中間件(Spider Middlewares),介於Scrapy引擎和蜘蛛之間的鉤子框架,主要工作是處理蜘蛛的響應輸入和請求輸出。
- 調度中間件(Scheduler Middlewares),介於Scrapy引擎和調度之間的中間件,從Scrapy引擎發送到調度的請求和響應。
爬取流程
上圖綠線是數據流向,首先從初始URL開始,Scheduler會將其交給Downloader進行下載,下載之後會交給Spider進行分析,Spider分析出來的結果有兩種:一種是需要進一步抓取的鏈接,例如之前分析的「下一頁」的鏈接,這些東西會被傳回Scheduler;另一種是需要保存的數據,它們則被送到Item Pipeline那裡,那是對數據進行後期處理(詳細分析、過濾、存儲等)的地方。另外,在數據流動的通道里還可以安裝各種中間件,進行必要的處理。
數據流
Scrapy中的數據流由執行引擎控制,其過程如下:
- 引擎打開一個網站(open a domain),找到處理該網站的Spider並向該spider請求第一個要爬取的URL(s)。
- 引擎從Spider中獲取到第一個要爬取的URL並在調度器(Scheduler)以Request調度。
- 引擎向調度器請求下一個要爬取的URL。
- 調度器返回下一個要爬取的URL給引擎,引擎將URL通過下載中間件(請求(request)方向)轉發給下載器(Downloader)。
- 一旦頁面下載完畢,下載器生成一個該頁面的Response,並將其通過下載中間件(返回(response)方向)發送給引擎。
- 引擎從下載器中接收到Response並通過Spider中間件(輸入方向)發送給Spider處理。
- Spider處理Response並返回爬取到的Item及(跟進的)新的Request給引擎。
- 引擎將(Spider返回的)爬取到的Item給Item Pipeline,將(Spider返回的)Request給調度器。
- (從第二步)重複直到調度器中沒有更多地request,引擎關閉該網站。
Scrapy項目基本流程
默認的Scrapy項目結構
使用全局命令startproject創建項目,在project_name文件夾下創建一個名為project_name的Scrapy項目。
scrapy startproject myprojectn
雖然可以被修改,但所有的Scrapy項目默認有類似於下邊的文件結構:
scrapy.cfgnmyproject/n __init__.pyn items.pyn pipelines.pyn settings.pyn spiders/n __init__.pyn spider1.pyn spider2.pyn ... nscrapy.cfg 存放的目錄被認為是 項目的根目錄 。該文件中包含python模塊名的欄位定義了項目的設置。n
定義要抓取的數據
Item 是保存爬取到的數據的容器;其使用方法和python字典類似, 並且提供了額外保護機制來避免拼寫錯誤導致的未定義欄位錯誤。
類似在ORM中做的一樣,您可以通過創建一個 scrapy.Item 類, 並且定義類型為 scrapy.Field 的類屬性來定義一個Item。首先根據需要從http://dmoz.org(DMOZ網站是一個著名的開放式分類目錄(Open DirectoryProject),由來自世界各地的志願者共同維護與建設的最大的全球目錄社區)獲取到的數據對item進行建模。 我們需要從dmoz中獲取名字,url,以及網站的描述。 對此,在item中定義相應的欄位。編輯items.py 文件:
import scrapynnclass DmozItem(scrapy.Item):n title = scrapy.Field()n link = scrapy.Field()n desc = scrapy.Field()n
使用項目命令genspider創建Spider
scrapy genspider [-t template] <name> <domain>n
在當前項目中創建spider。
這僅僅是創建spider的一種快捷方法。該方法可以使用提前定義好的模板來生成spider。您也可以自己創建spider的源碼文件。$ scrapy genspider -lnAvailable templates:n basicn crawln csvfeedn xmlfeednn$ scrapy genspider -d basicnimport scrapynnclass $classname(scrapy.Spider):n name = "$name"n allowed_domains = ["$domain"]n start_urls = (n http://www.$domain/,n )nn def parse(self, response):n passnn$ scrapy genspider -t basic example example.comnCreated spider example using template basic in module:n mybot.spiders.examplen
編寫提取item數據的Spider
Spider是用戶編寫用於從單個網站(或者一些網站)爬取數據的類。
其包含了一個用於下載的初始URL,如何跟進網頁中的鏈接以及如何分析頁面中的內容, 提取生成 item 的方法。為了創建一個Spider,您必須繼承 scrapy.Spider 類,且定義以下三個屬性:- name: 用於區別Spider。 該名字必須是唯一的,您不可以為不同的Spider設定相同的名字。
- start_urls: 包含了Spider在啟動時進行爬取的url列表。 因此,第一個被獲取到的頁面將是其中之一。 後續的URL則從初始的URL獲取到的數據中提取。
- parse() 是spider的一個方法。 被調用時,每個初始URL完成下載後生成的 Response 對象將會作為唯一的參數傳遞給該函數。 該方法負責解析返回的數據(response data),提取數據(生成item)以及生成需要進一步處理的URL的 Request 對象。
import scrapynnclass DmozSpider(scrapy.spider.Spider):n name = "dmoz" #唯一標識,啟動spider時即指定該名稱n allowed_domains = ["dmoz.org"]n start_urls = [n "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",n "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"n ]nn def parse(self, response):n filename = response.url.split("/")[-2]n with open(filename, wb) as f:n f.write(response.body)n
進行爬取
執行項目命令crawl,啟動Spider:
scrapy crawl dmozn
在這個過程中:
Scrapy為Spider的 start_urls 屬性中的每個URL創建了 scrapy.Request 對象,並將 parse 方法作為回調函數(callback)賦值給了Request。Request對象經過調度,執行生成 scrapy.http.Response 對象並送回給spider parse() 方法。通過選擇器提取數據
Selectors選擇器簡介:
Scrapy提取數據有自己的一套機制。它們被稱作選擇器(seletors),因為他們通過特定的 XPath 或者 CSS 表達式來「選擇」 HTML文件中的某個部分。XPath 是一門用來在XML文件中選擇節點的語言,也可以用在HTML上。 CSS 是一門將HTML文檔樣式化的語言。選擇器由它定義,並與特定的HTML元素的樣式相關連。XPath表達式的例子和含義:
- /html/head/title: 選擇HTML文檔中 <head> 標籤內的 <title> 元素
- /html/head/title/text(): 選擇上面提到的 <title> 元素的文字
- //td: 選擇所有的 <td> 元素
- //div[@class="mine"]: 選擇所有具有 class="mine" 屬性的 div 元素
提取數據:
觀察HTML源碼並確定合適的XPath表達式。
在查看了網頁的源碼後,您會發現網站的信息是被包含在 第二個元素中。我們可以通過這段代碼選擇該頁面中網站列表裡所有元素:response.xpath(//ul/li)Item 對象是自定義的python字典。 您可以使用標準的字典語法來獲取到其每個欄位的值。一般來說,Spider將會將爬取到的數據以 Item 對象返回。所以為了將爬取的數據返回,我們最終的代碼將是:import scrapynnfrom tutorial.items import DmozItemnnclass DmozSpider(scrapy.Spider):n name = "dmoz"n allowed_domains = ["dmoz.org"]n start_urls = [n "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",n "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"n ]nn def parse(self, response): for sel in response.xpath(//ul/li):n item = DmozItem()n item[title] = sel.xpath(a/text()).extract()n item[link] = sel.xpath(a/@href).extract()n item[desc] = sel.xpath(text()).extract()n yield itemn
現在對http://dmoz.org進行爬取將會產生 DmozItem 對象。
保存數據
最簡單存儲爬取的數據的方式是使用 Feed exports:
scrapy crawl dmoz -o items.jsonn
該命令將採用 JSON 格式對爬取的數據進行序列化,生成 items.json 文件。
如果需要對爬取到的item做更多更為複雜的操作,您可以編寫 Item Pipeline 。類似於我們在創建項目時對Item做的,用於您編寫自己的 tutorial/pipelines.py 也被創建。不過如果您僅僅想要保存item,您不需要實現任何的pipeline。補充提示:Windows平台安裝Scrapy的特別要求
Windows specific installation notes
Windows平台下,安裝Scrapy之前首先要進行以下操作:- 安裝OpenSSL在Win32 OpenSSL page中下載安裝Visual C++ 2008 redistributables和對應的OpenSSL安裝包,並把其可執行文件目錄「*openssl-win32bin」加入到環境變數Path中
- 安裝Scrapy依賴的二進位包pywin32 Twisted zope.interface lxml pyOpenSSL
小結
第一篇關於Scrapy的文章主要依據Scrapy 0.24的中文文檔,了解、熟悉Scrapy的使用和基本概念,在後面的相關文章中,將進一步加入自己的思考和自行編寫的程序,期待能在這個過程中提高自己,也希望能對看到這些文章的讀者有用。
參考資料
Scrapy架構概覽 初窺Scrapy Scrapy入門教程 如何入門 Python 爬蟲
轉載請註明作者Jason Ding及其出處 Github博客主頁(http://jasonding1354.github.io/) CSDN博客(http://blog.csdn.net/jasonding1354) 簡書主頁(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)
作者:JasonDing
鏈接:http://www.jianshu.com/p/a8aad3bf4dc4來源:簡書著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。推薦閱讀:
※第十一章 Scrapy入門程序點評
※關於在pycharm中配置導入路徑的問題?
※如何用scrapy爬取搜房網上小區的坐標值?
※Python網頁信息採集:使用PhantomJS採集某貓寶商品內容
※【記錄】Scrapy模擬登錄cookie失效問題