Scray框架工做原理

Date: 2019-07-07html

Author: Sunpython

1 定義

Scrapy,Python開發的一個快速、高層次的屏幕抓取和web抓取框架,用於抓取web站點並從頁面中提取結構化的數據。Scrapy用途普遍,能夠用於數據挖掘、監測和自動化測試。web

Scrapy是一個爲遍歷爬行網站、分解獲取數據而設計的應用程序框架,它能夠應用在普遍領域:數據挖掘、信息處理和或者歷史片(歷史記錄)打包等等shell

官方網站:http://scrapy.org數據庫

2 安裝

scrapy框架的安裝依賴於異步網絡庫twisted,安裝過程很簡單。cookie

進入到python虛擬環境下:網絡

pip install Scrapy架構

安裝過程當中可能存在以下問題?框架

building 'twisted.test.raiser' extension
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools異步

解決方案
​ 進入下載頁面:http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
​ 下載twisted對應版本的whl文件(如個人Twisted-17.5.0-cp36-cp36m-win_amd64.whl),cp後面是python版本,amd64表明64位,運行命令:
​ pip install C:\Users\CR\Downloads\Twisted-17.5.0-cp36-cp36m-win_amd64.whl

在此安裝scrapy

pip install Scrapy

說明:

​ 若是發現哪一個庫安裝失敗,則經過wget下載https://pypi.org/simple/中相應版本的庫,並安裝,最後安裝就能夠成功

3 Scrapy工做原理

​ Scrapy框架主要由六大組件組成,它們分別是調試器(Scheduler)、下載器(Downloader)、爬蟲(Spider)、中間件(Middleware)、實體管道(Item Pipeline)和Scrapy引擎(Scrapy Engine)

3.1 組件圖

下面的圖表顯示了Scrapy架構組件。

scrapy基本組件圖

組件說明:

(1)Scrapy Engine

引擎負責控制數據流在系統中全部組件中流動,並在相應動做發生時觸發事件。

(2)調度器(Scheduler)

調度器從引擎接受request對象,並將他們入隊列,以便以後引擎請求他們時提供給引擎。

(3)下載器(Downloader)

下載器負責獲取頁面數據並提供給引擎,然後提供給spiders。

(4)Spiders

Spider是Scrapy用戶編寫用於分析response並提取item(即獲取到的item)或額外跟進的URL的類。 每一個spider負責處理一個特定(或一些)網站。 更多內容請看 Spiders

(5)Item Pipeline

Item Pipeline負責處理被spider提取出來的item。典型的處理有清理、 驗證及持久化(例如存取到數據庫中)。 更多內容查看 Item Pipeline。

(6)下載器中間件(Downloader middlewares)

下載器中間件是在引擎及下載器之間的特定鉤子(specific hook),處理Downloader傳遞給引擎的response(也包括引擎傳遞給下載器的Request)。 其提供了一個簡便的機制,經過插入自定義代碼來擴展Scrapy功能。更多內容請看 下載器中間件(Downloader Middleware) 。

一句話總結就是:處理下載請求部分

(7)Spider中間件(Spider middlewares)

Spider中間件是在引擎及Spider之間的特定鉤子(specific hook),處理spider的輸入(response)和輸出(items及requests)。 其提供了一個簡便的機制,經過插入自定義代碼來擴展Scrapy功能。更多內容請看 Spider中間件(Middleware)

3.2. scrapy數據流圖

數據流程圖以下:

scrapy數據流圖

Scrapy數據流圖是由執行的核心引擎(engine)控制,流程是這樣的:

一、爬蟲引擎得到初始請求開始抓取。

二、爬蟲引擎開始請求調度程序,並準備對下一次的請求進行抓取。

三、爬蟲調度器返回下一個請求給爬蟲引擎。

四、引擎請求發送到下載器,經過下載中間件下載網絡數據。

五、一旦下載器完成頁面下載,將下載結果返回給爬蟲引擎。

六、引擎將下載器的響應經過中間件返回給爬蟲進行處理。

七、爬蟲處理響應,並經過中間件返回處理後的items,以及新的請求給引擎。

八、引擎發送處理後的items到項目管道,而後把處理結果返回給調度器,調度器計劃處理下一個請求抓取。

九、重複該過程(繼續步驟1),直到爬取完全部的url請求。

4. Scrapy 請求響應內部組件

4.1. 請求和響應(Request, Response)

Scrapy的Request和Response對象用於爬取web網站。

通常來講,Request對象在spider中被生成而且最終傳遞到下載器(Downloader),下載器對其進行處理並返回一個Response對象,Response對象還會返回到生成requestspider中。

4.2. Request對象

一個Request對象表明一個HTTP請求,通常來說,HTTP請求是由Spider產生並被Downloader處理進而生成一個Response。

4.2.1 構造方法:

class scrapy.http.Request(url[, callback, method='GET', headers, body, cookies, meta, encoding='utf-8', priority=0, dont_filter=False, errback, flags])

一個Request對象表示一個HTTP 請求,它一般在Spider中生成並由Downloader執行,從而生成一個。

參數:    
url(string):請求的url

callback(callable):處理響應數據的回調方法,用來解析響應數據,若是沒有指定,則spider的parse方法。若是在處理期間引起異常,則會調用errback。

method(string):HTTP的請求方法。默認GET。

meta(dict):Request.meta屬性的初始值。一旦此參數被設置,經過參數傳遞的字典將會被淺拷貝。

body:請求體。

headers(dict):請求頭。

cookies(dict):cookie

encoding(string):編碼方式,默認utf-8。

priority(int):優先級,調度程序使用優先級來定義用於處理請求的順序。具備較高優先級值的請求將會提早執行。默認0。

dont_filter(boolean):請求不該該被調度器過濾。False表示過濾,True表示不過濾。默認False。

errback(callable):若是在處理請求時引起異常,將會調用該函數。 這包括404 HTTP錯誤等失敗的頁面。

4.2.2. Request.meta

Request.meta在不一樣的請求之間傳遞數據使用的

Request.meta屬性能夠包含任意的數據,可是Scrapy和它的內置擴展能夠識別一些特殊的鍵。

dont_redirect:不重定向
dont_retry:不重試
handle_httpstatus_list
dont_merge_cookies:不合並cookie
cookiejar:使用cookiejar
redirect_urls:重定向鏈接
bindaddress:綁定ip地址
dont_obey_robotstxt:不遵循反爬蟲協議
download_timeout:下載超時

4.2.3. Request的子類FormRequest

FormRequest是Request的子類,通常用做表單數據提交。

FormRequest的構造:
class scrapy.http.FormRequest(url[,formdata,...])

FormRequest類除了有Request的功能

還提供一個form_response()方法:

form_response(response[,formname=None,formnumber=0,formdata=None,formxpath=None,clickdata=None,dont_click=False,...])


response:是指包含HTML表單的Response對象,該表單將用於預填充表單字段。

formname:若是給定,將使用設置爲該值的name屬性的表單。

formnumber:當響應包含多個表單時,要使用的表單的數量。 formnumber默認是0,表示使用第一個。

formdata:字段來覆蓋表單數據。若是一個字段已經存在於響應<form>元素中,那麼它的值被在這個參數中傳遞的值覆蓋。

formxpath:若是給定,將使用與XPath匹配的第一個表單。

clickdata:查找單擊控件的屬性。若是沒有給出,表單數據將被提交模擬點擊第一個可點擊的元素。

dont_click:若是爲True,表單數據將被提交而不須要單擊任何元素。

4.3. Response對象

HTTP請求返回的響應對象,它一般被下載(由Downloader)下載並被傳送給Spider進行處理。

4.3.1. 構造函數

class scrapy.http.Response(url[,status=200,headers,body,flags])

url:響應對象response的url

headers:響應對象的響應報頭

status:響應的狀態碼,默認200。

body:響應體

meta:爲response.meta屬性的初始值。若是給定的,字典將淺複製。

flags:是一個列表包含的response.flags初始值的屬性。若是給定,列表將被淺拷貝。

TextResponse

class scrapy.http.TextResponse(url[,encoding[,...]])

TextResponse對象增長了編碼能力的基礎響應類,是指將只用於二進制數據,如圖像、聲音或任何媒體文件。

4.3.2 發送FormRequest表單請求

​ FormRequest新增長了一個參數formdata,接受包含表單數據的字典或者可迭代的元組,並將其轉化爲請求的body。而且FormRequest是繼承Request的

# 發送FormRequest表單請求
        return FormRequest.from_response(response=response,
                                         meta={'cookiejar': response.meta['cookiejar']},
                                         headers=self.post_headers,
                                         formdata={
                                             "utf8": utf8,
                                             "authenticity_token": authenticity_token,
                                             "login": login,
                                             "password": password,
                                             "commit": commit
                                         },
                                         callback=self.after_login)

案例

有時候須要解析頁面嵌套,能夠採用callback, 解析頁面page1,經過解析頁面page2解析另外一個url

parse_page1 由url1產生response

def parse_page1(self, response):
    item = MyItem()
    item['main_url'] = response.url
    request = scrapy.Request("http://www.example.com/some_page.html",
                             callback=self.parse_page2)
    request.meta['item'] = item
    yield request   #將request對象發送到scheduler裏面   中間要通過(request --> scheduler --> engine --> downloader --> engine --> spiders(response))


def parse_page2(self, response):
    item = response.meta['item']
    item['other_url'] = response.url
    return item    #將item結果數據發送到pipeline裏面去  結果數據 item --> pipeline
相關文章
相關標籤/搜索