天天看點

你懂Scrapy嗎?Scrapy大型爬蟲架構講解【一】

你懂Scrapy嗎?Scrapy大型爬蟲架構講解【一】

這是scrapy爬蟲架構的第一篇,本系列專題将包含以下内容:

介紹scrapy架構的主體以及各個元件的意義;

舉執行個體講解其具體應用。

開始第一節: 介紹scrapy架構的主體以及各個元件的意義。

scrapy是一個為了爬取網站資料,提取結構性資料而編寫的應用架構。 可以應用在包括資料挖掘,資訊處理或存儲曆史資料等一系列的程式中。

其最初是為了 頁面抓取 (更确切來說, 網絡抓取 )所設計的, 也可以應用在擷取api所傳回的資料(例如 amazon associates web services ) 或者通用的網絡爬蟲。

安裝scrapy需要一些依賴:

python

python package: pip and setuptools. 現在 pip 依賴 setuptools ,如果未安裝,則會自動安裝setuptools 。

lxml. 大多數linux發行版自帶了lxml。如果缺失,請檢視 installing lxml

openssl. 除了windows(請檢視 平台安裝指南)之外的系統都已經提供。

當安裝好這些依賴之後,隻需要運作pip install scrapy,即可安裝完scrapy。

然後運作:

scrapy startproject tutorial 

即可自動建立官方标準的代碼目錄。

tutorial/ 

    scrapy.cfg 

    tutorial/ 

        __init__.py 

        items.py 

        pipelines.py 

        settings.py 

        spiders/ 

            __init__.py 

            ...  

其中:

tutorial/: 該項目的python總子產品。

tutorial/items.py: 項目中的item檔案,編寫爬取的字段名稱等;

tutorial/pipelines.py: 項目中的pipelines檔案;

tutorial/settings.py: 項目的設定檔案,較為重要;

tutorial/spiders/: 放置spider代碼的主目錄;

scrapy整體架構神圖:

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,引擎關閉該網站。

以上是老生常談,下面談一些經驗:

如果需要大批量分布式爬取,建議采用redis資料庫存儲,可安裝scrapy-redis,使用redis資料庫來替換scrapy原本使用的隊列結構(deque),并配合其它資料庫存儲,例如mysql或者mongodb,爬取效率将會極大提高。并且其自帶的dupefilter.py負責執行requst的去重,使用redis的set資料結構,通過settings檔案正确設定後,即便停止scrapy爬蟲,當下次重新開始後也能自動去重。原因就是在redis已經存儲了request的資訊。

當涉及到代理ip,headers頭中間請求資訊處理的時候,可以通過中間件middleware來實作。spider中間件是介入到scrapy的spider處理機制的鈎子架構,可以添加代碼來處理發送給 spiders的response及spider産生的item和request。

合理設定settings檔案,需要熟練掌握 settings 的各種設定。

可以重新定義def start_requests(self)函數來加載cookie資訊,form資訊的送出用scrapy.formrequest以及scrapy.formrequest.from_response這兩個函數,scrapy.formrequest.from_response能實作自動送出form資料。

采用scrapy+phantomjs,。 downloadmiddleware 對從 scheduler 送來的 request 對象在請求之前進行預處理,可以實作添加 headers, user_agent,還有 cookie 等功能 。但也可以通過中間件直接傳回 htmlresponse 對象,略過請求的子產品,直接扔給 response 的回調函數處理。

class custommetamiddleware(object): 

    def process_request(self,request,spider): 

        dcap = dict(desiredcapabilities.phantomjs)      

        dcap["phantomjs.page.settings.loadimages"] = false   

        dcap["phantomjs.page.settings.resourcetimeout"] = 10 

        driver = webdriver.phantomjs("d:xx\xx",desired_capabilities=dcap) 

        driver.get(request.url) 

        body = driver.page_source.encode('utf8') 

        url = driver.current_url 

        driver.quit() 

        return htmlresponse(request.url,body=body)  

綜上,是對scrapy的各個元件一些個人的經驗總結。

本文作者:蚍蜉撼大樹

來源:51cto