scrapy爬蟲安裝:
首先,安裝Python,pip,然後使用pip安裝lxml和scrapy,這樣就可以新建scrapy項目了。
然後,在命令行使用scrapy startproject xxx命令新建一個名為xxx的scrapy爬蟲項目。
喜歡的可以關注,稍後會發出一篇使用scrapy實戰爬取亞馬遜商品評論數據的文章!
scrapy爬蟲內部處理流程:
我們在使用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()方法。
在scrapy封裝Response後,會把該Response傳遞給parse()方法處理。scrapy.spiders.Spider中的parse()方法就是默認提供給用戶來實現的。在這個parse方法中,我們可以通過傳進來的Response對象,使用scrapy的選擇器和xpath()或者css()提取出我們想要的內容,封裝成我們在pipeline中定義的Item對象返回。或者,如果有下一頁的數據或者其他頁面的數據,在parse()方法中解析出來這樣的鏈接之後,我們也可以用這些鏈接生成Request對象返回。parse()方法可以返回一個Item對象、dict、Request對象,或者是一個包括這三個者的可迭代對象。或者我們也可以在生成Request的時候指定自定義的回調函數,不使用parse()方法。
如果parse()方法或回調函數返回的是一個Request對象,那麼scrapy.spiders.Spider會將這個Request對象交給scrapy主流程處理,發出HTTP請求,獲取響應,之後又生成Response對象, 傳遞給Request中設置的回調函數進行處理。也就是不斷地執行第二步和第三步。
如果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主要屬性和方法如下:
官方使用示例為:
scrapy.spiders.CrawlSpider:
CrawlSpider繼承自Spider,是一個適用於爬取很規則的網站的爬蟲。其定義了提取鏈接的規則,能夠很方便的從Response中提取到想要的鏈接並且繼續跟進這些鏈接。
CrawlSpider主要屬性如下:
其中,Rule有以下幾個參數:
其中LinkExtractor對象主要有以下幾個參數:
最常用的LinkExtractor為LxmlLinkExtractor,其使用了lxml中的HTMLParser來提取HTML內容,源碼為:
看了這麼多,我們最終來看一下CrawlSpider使用示例,如:
Spider.start_requests()方法:
由上面得知,scrapy.spiders.Spider會通過調用start_requests()方法,以start_urls中的所有鏈接的每個鏈接生成對應的Request對象,該對象設置了默認的回調函數parse()方法。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對象。如,
start_requests()方法默認會取start_urls中所有的鏈接來生成Request對象。既然我們可以自定義實現start_requests()方法,我們在start_requests()中也可以不使用start_urls,使用我們自定義的url生成Request就行,同時,我們還能給Request隨意指定我們想要的回調函數。
Request構造方法如下,可以看到,必備的參數只有url,其他都是可選參數,如,
對於需要登錄或者需要驗證cookie才能訪問的網頁,我們也可以使用scrapy來模擬登錄,獲取到cookie。這個時候,就不要使用默認的Request了,而是用FormRequest。從名字能夠看出,FormRequest天生就是為了在請求中模擬網頁上的表單而存在的。
FormRequest繼承了Request類,FormRequest只比Request多了一個候選參數formdata,其他參數和Request一樣。所以我們在創建FormRequest時,可以設置formdata參數來模擬出表單數據。
創建FormRequest的方法如下:
這是FormRequest類的一個靜態方法。
scrapy官方給出的FormRequest使用示例如下:
我們自己使用FormRequest模擬登錄的示例如下:
喜歡的可以關注,稍後會發出一篇使用scrapy實戰爬取亞馬遜商品評論數據的文章!