【scrapy】學習Scrapy入門

轉自http://www.jianshu.com/p/a8aad3bf4dc4


Scrapy介紹

Scrapy是一個爲了爬取網站數據,提取結構性數據而編寫的應用框架。 能夠應用在包括數據挖掘,信息處理或存儲歷史數據等一系列的程序中。
所謂網絡爬蟲,就是一個在網上處處或定向抓取數據的程序,固然,這種說法不夠專業,更專業的描述就是,抓取特定網站網頁的HTML數據。抓取網頁的通常方法是,定義一個入口頁面,而後通常一個頁面會有其餘頁面的URL,因而從當前頁面獲取到這些URL加入到爬蟲的抓取隊列中,而後進入到新頁面後再遞歸的進行上述的操做,其實說來就跟深度遍歷或廣度遍歷同樣。
Scrapy 使用 Twisted這個異步網絡庫來處理網絡通信,架構清晰,而且包含了各類中間件接口,能夠靈活的完成各類需求。html

總體架構


  • 引擎(Scrapy Engine),用來處理整個系統的數據流處理,觸發事務。python

  • 調度器(Scheduler),用來接受引擎發過來的請求,壓入隊列中,並在引擎再次請求的時候返回。git

  • 下載器(Downloader),用於下載網頁內容,並將網頁內容返回給蜘蛛。github

  • 蜘蛛(Spiders),蜘蛛是主要幹活的,用它來制訂特定域名或網頁的解析規則。編寫用於分析response並提取item(即獲取到的item)或額外跟進的URL的類。 每一個spider負責處理一個特定(或一些)網站。web

  • 項目管道(Item Pipeline),負責處理有蜘蛛從網頁中抽取的項目,他的主要任務是清晰、驗證和存儲數據。當頁面被蜘蛛解析後,將被髮送到項目管道,並通過幾個特定的次序處理數據。redis

  • 下載器中間件(Downloader Middlewares),位於Scrapy引擎和下載器之間的鉤子框架,主要是處理Scrapy引擎與下載器之間的請求及響應。json

  • 蜘蛛中間件(Spider Middlewares),介於Scrapy引擎和蜘蛛之間的鉤子框架,主要工做是處理蜘蛛的響應輸入和請求輸出。windows

  • 調度中間件(Scheduler Middlewares),介於Scrapy引擎和調度之間的中間件,從Scrapy引擎發送到調度的請求和響應。網絡

爬取流程

上圖綠線是數據流向,首先從初始URL開始,Scheduler會將其交給Downloader進行下載,下載以後會交給Spider進行分析,Spider分析出來的結果有兩種:一種是須要進一步抓取的連接,例如以前分析的「下一頁」的連接,這些東西會被傳回Scheduler;另外一種是須要保存的數據,它們則被送到Item Pipeline那裏,那是對數據進行後期處理(詳細分析、過濾、存儲等)的地方。另外,在數據流動的通道里還能夠安裝各類中間件,進行必要的處理。架構

數據流

Scrapy中的數據流由執行引擎控制,其過程以下:

  1. 引擎打開一個網站(open a domain),找處處理該網站的Spider並向該spider請求第一個要爬取的URL(s)。

  2. 引擎從Spider中獲取到第一個要爬取的URL並在調度器(Scheduler)以Request調度。

  3. 引擎向調度器請求下一個要爬取的URL。

  4. 調度器返回下一個要爬取的URL給引擎,引擎將URL經過下載中間件(請求(request)方向)轉發給下載器(Downloader)。

  5. 一旦頁面下載完畢,下載器生成一個該頁面的Response,並將其經過下載中間件(返回(response)方向)發送給引擎。

  6. 引擎從下載器中接收到Response並經過Spider中間件(輸入方向)發送給Spider處理。

  7. Spider處理Response並返回爬取到的Item及(跟進的)新的Request給引擎。

  8. 引擎將(Spider返回的)爬取到的Item給Item Pipeline,將(Spider返回的)Request給調度器。

  9. (從第二步)重複直到調度器中沒有更多地request,引擎關閉該網站。

Scrapy項目基本流程

默認的Scrapy項目結構

使用全局命令startproject建立項目,在project_name文件夾下建立一個名爲project_name的Scrapy項目。

scrapy startproject myproject

雖然能夠被修改,但全部的Scrapy項目默認有相似於下邊的文件結構:

scrapy.cfg
myproject/
    __init__.py
    items.py
    pipelines.py
    settings.py
    spiders/
        __init__.py
        spider1.py
        spider2.py        ...

scrapy.cfg 存放的目錄被認爲是 項目的根目錄 。該文件中包含python模塊名的字段定義了項目的設置。

定義要抓取的數據

Item 是保存爬取到的數據的容器;其使用方法和python字典相似, 而且提供了額外保護機制來避免拼寫錯誤致使的未定義字段錯誤。
相似在ORM中作的同樣,您能夠經過建立一個 scrapy.Item 類, 而且定義類型爲 scrapy.Field 的類屬性來定義一個Item。
首先根據須要從dmoz.org(DMOZ網站是一個著名的開放式分類目錄(Open DirectoryProject),由來自世界各地的志願者共同維護與建設的最大的全球目錄社區)獲取到的數據對item進行建模。 咱們須要從dmoz中獲取名字,url,以及網站的描述。 對此,在item中定義相應的字段。編輯items.py 文件:

import scrapyclass DmozItem(scrapy.Item):
    title = scrapy.Field()
    link = scrapy.Field()
    desc = scrapy.Field()

使用項目命令genspider建立Spider

scrapy genspider [-t template] <name> <domain>

在當前項目中建立spider。
這僅僅是建立spider的一種快捷方法。該方法可使用提早定義好的模板來生成spider。您也能夠本身建立spider的源碼文件。

$ scrapy genspider -l
Available templates:
  basic
  crawl
  csvfeed
  xmlfeed

$ scrapy genspider -d basicimport scrapyclass $classname(scrapy.Spider):
    name = "$name"
    allowed_domains = ["$domain"]
    start_urls = (        'http://www.$domain/',
        )    def parse(self, response):
        pass$ scrapy genspider -t basic example example.com
Created spider 'example' using template 'basic' in module:
  mybot.spiders.example

編寫提取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 scrapyclass DmozSpider(scrapy.spider.Spider):
    name = "dmoz"    #惟一標識,啓動spider時即指定該名稱
    allowed_domains = ["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]        with open(filename, 'wb') as f:
            f.write(response.body)

進行爬取

執行項目命令crawl,啓動Spider:

scrapy crawl dmoz

在這個過程當中:
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 scrapyfrom tutorial.items import DmozItemclass DmozSpider(scrapy.Spider):
        name = "dmoz"
        allowed_domains = ["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):
            for sel in response.xpath('//ul/li'):
                item = DmozItem()
                item['title'] = sel.xpath('a/text()').extract()
                item['link'] = sel.xpath('a/@href').extract()
                item['desc'] = sel.xpath('text()').extract()            yield item

    如今對dmoz.org進行爬取將會產生 DmozItem 對象。

    保存數據

    最簡單存儲爬取的數據的方式是使用 Feed exports:

    scrapy crawl dmoz -o items.json

    該命令將採用 JSON 格式對爬取的數據進行序列化,生成 items.json 文件。
    若是須要對爬取到的item作更多更爲複雜的操做,您能夠編寫 Item Pipeline 。相似於咱們在建立項目時對Item作的,用於您編寫本身的 tutorial/pipelines.py 也被建立。不過若是您僅僅想要保存item,您不須要實現任何的pipeline。

    補充提示:Windows平臺安裝Scrapy的特別要求

    Windows specific installation notes
    Windows平臺下,安裝Scrapy以前首先要進行如下操做:

    小結

    第一篇關於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著做權歸做者全部,轉載請聯繫做者得到受權,並標註「簡書做者」。

相關文章
相關標籤/搜索