Date: 2019-07-07html
Author: Sunpython
Scrapy,Python開發的一個快速、高層次的屏幕抓取和web抓取框架,用於抓取web站點並從頁面中提取結構化的數據。Scrapy用途普遍,能夠用於數據挖掘、監測和自動化測試。web
Scrapy是一個爲遍歷爬行網站、分解獲取數據而設計的應用程序框架,它能夠應用在普遍領域:數據挖掘、信息處理和或者歷史片(歷史記錄)打包等等shell
官方網站:http://scrapy.org數據庫
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/中相應版本的庫,並安裝,最後安裝就能夠成功
Scrapy框架主要由六大組件組成,它們分別是調試器(Scheduler)、下載器(Downloader)、爬蟲(Spider)、中間件(Middleware)、實體管道(Item Pipeline)和Scrapy引擎(Scrapy Engine)
下面的圖表顯示了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) 。
數據流程圖以下:
scrapy數據流圖
Scrapy數據流圖是由執行的核心引擎(engine)控制,流程是這樣的:
一、爬蟲引擎得到初始請求開始抓取。
二、爬蟲引擎開始請求調度程序,並準備對下一次的請求進行抓取。
三、爬蟲調度器返回下一個請求給爬蟲引擎。
四、引擎請求發送到下載器,經過下載中間件下載網絡數據。
五、一旦下載器完成頁面下載,將下載結果返回給爬蟲引擎。
六、引擎將下載器的響應經過中間件返回給爬蟲進行處理。
七、爬蟲處理響應,並經過中間件返回處理後的items,以及新的請求給引擎。
八、引擎發送處理後的items到項目管道,而後把處理結果返回給調度器,調度器計劃處理下一個請求抓取。
九、重複該過程(繼續步驟1),直到爬取完全部的url請求。
Scrapy的Request和Response對象用於爬取web網站。
通常來講,Request對象在
spider
中被生成而且最終傳遞到下載器(Downloader
),下載器對其進行處理並返回一個Response
對象,Response
對象還會返回到生成request
的spider
中。
一個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,表單數據將被提交而不須要單擊任何元素。
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
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