Python爬蟲框架之Scrapy詳解

編程語言 Scrapy 網絡爬蟲 Python 開發技術專注者 2017-05-21

scrapy爬蟲安裝

  1. 首先,安裝Python,pip,然後使用pip安裝lxml和scrapy,這樣就可以新建scrapy項目了。

  2. 然後,在命令行使用scrapy startproject xxx命令新建一個名為xxx的scrapy爬蟲項目。

喜歡的可以關注,稍後會發出一篇使用scrapy實戰爬取亞馬遜商品評論數據的文章!


scrapy爬蟲內部處理流程:

  1. 我們在使用scrapy寫爬蟲,一般要繼承scrapy.spiders.Spider類,在這個類中,有個數組類型的變量start_urls,start_urls定義了爬蟲開始爬取的那些鏈接,所以我們會把需要先爬取的頁面鏈接放入start_urls中。然後,scrapy.spiders.Spider會通過調用start_requests()方法,以start_urls中的所有鏈接的每個鏈接生成對應的Request對象,該對象設置了默認的回調函數parse()方法。然後,scrapy主流程會用該Request對象發HTTP請求並且獲取到相應內容,封裝成Response對象,然後這個Response對象會被作為參數傳遞給Request設置的回調函數,也就是parse()方法。這裡要注意,start_requests()方法是Spider提供的,本來就實現好的,一般情況下不需要自己去實現start_requests()方法。

  2. 在scrapy封裝Response後,會把該Response傳遞給parse()方法處理。scrapy.spiders.Spider中的parse()方法就是默認提供給用戶來實現的。在這個parse方法中,我們可以通過傳進來的Response對象,使用scrapy的選擇器和xpath()或者css()提取出我們想要的內容,封裝成我們在pipeline中定義的Item對象返回。或者,如果有下一頁的數據或者其他頁面的數據,在parse()方法中解析出來這樣的鏈接之後,我們也可以用這些鏈接生成Request對象返回。parse()方法可以返回一個Item對象、dict、Request對象,或者是一個包括這三個者的可迭代對象。或者我們也可以在生成Request的時候指定自定義的回調函數,不使用parse()方法。

  3. 如果parse()方法或回調函數返回的是一個Request對象,那麼scrapy.spiders.Spider會將這個Request對象交給scrapy主流程處理,發出HTTP請求,獲取響應,之後又生成Response對象, 傳遞給Request中設置的回調函數進行處理。也就是不斷地執行第二步和第三步。

  4. 如果parse()方法或回調函數返回的是Item對象,那scrapy.spiders.Spider會把這個返回的Item傳遞給scrapy中的Item Pipeline處理。所以,在實現爬蟲的時候,一般都要定義一個ItemPipeline來處理我們在回調函數中返回的Item。在pipeline中,我們可以把Item輸出,持久化到數據庫或者文件中。


scrapy.spiders.Spider :

scrapy.spiders.Spider是scrapy中最簡單的spider。一般要爬取的操作都定義在Spider類中。重寫Spider的parse方法來處理獲取到的網頁內容。

Spider主要屬性和方法如下:

Python爬蟲框架之Scrapy詳解

Spider主要屬性和方法

官方使用示例為:

Python爬蟲框架之Scrapy詳解

Spider官方示例


scrapy.spiders.CrawlSpider:

CrawlSpider繼承自Spider,是一個適用於爬取很規則的網站的爬蟲。其定義了提取鏈接的規則,能夠很方便的從Response中提取到想要的鏈接並且繼續跟進這些鏈接。

CrawlSpider主要屬性如下:

Python爬蟲框架之Scrapy詳解

CrawlSpider主要屬性和方法

其中,Rule有以下幾個參數:

Python爬蟲框架之Scrapy詳解

Rule參數

其中LinkExtractor對象主要有以下幾個參數:

Python爬蟲框架之Scrapy詳解

LinkExtractor參數

最常用的LinkExtractor為LxmlLinkExtractor,其使用了lxml中的HTMLParser來提取HTML內容,源碼為:

Python爬蟲框架之Scrapy詳解

LxmlLinkExtractor

看了這麼多,我們最終來看一下CrawlSpider使用示例,如:

Python爬蟲框架之Scrapy詳解

CrawlSpider


Spider.start_requests()方法:

由上面得知,scrapy.spiders.Spider會通過調用start_requests()方法,以start_urls中的所有鏈接的每個鏈接生成對應的Request對象,該對象設置了默認的回調函數parse()方法。start_requests()方法的默認實現如下:

Python爬蟲框架之Scrapy詳解

start_requests

我們如果要自定義先爬取的頁面時,或者要自己定義先生成的Request時,或者某些需要網站需要登錄才能訪問時,我們就會自己來實現start_request()方法,我們在實現該方法的時候,一般會參考它的默認實現,然後把start_requests()方法實現為一個包含yield的生成器。我們把想要先爬取的鏈接全部存放在start_urls列表中,然後對於這個列表中的每一個url來說,start_requests()方法只會調用一次,然後就會生成Request,獲取Response,將Response傳遞給Request中的回調函數處理。但這不是說在整個爬蟲項目的爬取過程中start_request()方法只會調用一次,而是說,對於start_urls中的每一個鏈接,start_requests()方法只會調用一次)。

所以如果我們實現了start_requests()方法,那麼我們會把它實現為生成器的形式,即,在start_requests()實現中,使用yield中通過make_requests_from_url(url)方法產生默認的Request對象或者我們自定義的Request對象。如,

Python爬蟲框架之Scrapy詳解

自定義start_requests實現

start_requests()方法默認會取start_urls中所有的鏈接來生成Request對象。既然我們可以自定義實現start_requests()方法,我們在start_requests()中也可以不使用start_urls,使用我們自定義的url生成Request就行,同時,我們還能給Request隨意指定我們想要的回調函數。

Request構造方法如下,可以看到,必備的參數只有url,其他都是可選參數,如,

Python爬蟲框架之Scrapy詳解

Request構造方法

對於需要登錄或者需要驗證cookie才能訪問的網頁,我們也可以使用scrapy來模擬登錄,獲取到cookie。這個時候,就不要使用默認的Request了,而是用FormRequest。從名字能夠看出,FormRequest天生就是為了在請求中模擬網頁上的表單而存在的。

FormRequest繼承了Request類,FormRequest只比Request多了一個候選參數formdata,其他參數和Request一樣。所以我們在創建FormRequest時,可以設置formdata參數來模擬出表單數據。

創建FormRequest的方法如下:

Python爬蟲框架之Scrapy詳解

from_response

這是FormRequest類的一個靜態方法。

scrapy官方給出的FormRequest使用示例如下:

Python爬蟲框架之Scrapy詳解

FormRequest官方示例

我們自己使用FormRequest模擬登錄的示例如下:

Python爬蟲框架之Scrapy詳解

FormRequest模擬登陸

喜歡的可以關注,稍後會發出一篇使用scrapy實戰爬取亞馬遜商品評論數據的文章!

Python爬蟲框架之Scrapy詳解

更多文章

  1. Java中最重要的併發編程抽象工具類

  2. Java執行系統命令、外部腳本或外部程序

  3. Java網絡爬蟲工具,OkHttp完全詳細用法

相關推薦

推薦中...