CrawlSpider也繼承自Spider,所以具備它的所有特性,這些特性上章已經講過了,就再在贅述了,這章就講點它本身所獨有的。
參與過網站后台開發的應該會知道,網站的url都是有一定規則的。像django,在view中定義的urls規則就是正則表示的。那么是不是可以根據這個特性來設計爬蟲,而不是每次都要用spider分析頁面格式,拆解源碼。回答是肯定的,scrapy提供了CrawlSpider處理此需求。
在CrawlSpider源碼中最先定義的是類Rule:
這個類非常的簡單,也只在這里使用,相信大家都能看懂,具體的會在下面用法那邊敘述,這邊就先跳過。
再來看看今天的硬菜CrawlSpider類的源碼:
rules:
有經驗的同學都知道它是一個列表,存儲的元素時Rule類的實例,其中每一個實例都定義了一種采集站點的行為。如果有多個rule都匹配同一個鏈接,那么位置下標最小的一個rule將會被使用。
__init__:
在源碼中可以看到,它主要就是執行了_compile_rules方法,這邊暫時不講。
parse:
默認回調方法,同上章一樣。不過在這里進行了重寫,這里直接調用方法_parse_response,並把parse_start_url方法作為處理response的方法。
parse_start_url:
這個方法在源碼中只看其定義是沒有什么發現的,需要查看其使用環境。它的主要作用就是處理parse返回的response,比如提取出需要的數據等,該方法也需要返回item、request或者他們的可迭代對象。它就是一個回調方法,和rule.callback用法一樣。
_requests_to_follow:
閱讀源碼可以發現,它的作用就是從response中解析出目標url,並將其包裝成request請求。該請求的回調方法是_response_downloaded,這里為request的meta值添加了rule參數,該參數的值是這個url對應rule在rules中的下標。
_response_downloaded:
該方法是方法_requests_to_follow的回調方法,作用就是調用_parse_response方法,處理下載器返回的response,設置response的處理方法為rule.callback方法。
_parse_response:
該方法將resposne交給參數callback代表的方法去處理,然后處理callback方法的requests_or_item。再根據rule.follow and spider._follow_links來判斷是否繼續采集,如果繼續那么就將response交給_requests_to_follow方法,根據規則提取相關的鏈接。spider._follow_links的值是從settings的CRAWLSPIDER_FOLLOW_LINKS值獲取到的。
_compile_rules:
這個方法的作用就是將rule中的字符串表示的方法改成實際的方法,方便以后使用。
from_crawler:
這個就不細說了,看看源碼就好,兩行代碼。
整個數據的流向如下圖所示:
關於CrawlSpider就先講到這里,接下來會說說Rule類,該類的源碼已經在文章的最上方貼出來了。
link_extractor:
該方法是一個Link Extractor實例,主要定義的就是鏈接的解析規則。
callback:
該值可以是一個方法,也可以是一個字符串(spider實例中一個方法的名稱)。它就是一個回調方法,在上面的流程圖中可以看到它所在的位置以及作用。這里要慎用parse做為回調方法,因為這邊的parse已經不像spider類中的那樣沒有具體操作。
cb_kwargs:
這是一個字典,用於給callback方法傳遞參數,在CrawlSpider源碼中可以看到其作用。
follow:
是一個布爾對象,表示是當前response否繼續采集。如果callback是None,那么它就默認為True,否則為False。
process_links:
該方法在crawlspider中的_requests_to_follow方法中被調用,它接收一個元素為Link的列表作為參數,返回值也是一個元素為Link的列表。可以用該方法對采集的Link對象進行修改,比如修改Link.url。這里的如果你的目標url是相對的鏈接,那么scrapy會將其擴展成絕對的。源碼就不帶大家看了,了解就行。
process_request:
顧名思義,該方法就是處理request的,源碼中也給出了一個樣例(雖然沒有任何作用),想修改request的小伙伴可以自己構造該方法。
Rule是不是很簡單呢,可是他的屬性link_extractor的花樣就比較多了。默認的link解析器是LinkExtractor,也就是LxmlLinkExtractor。在之前的scrapy版本中還有其他的解析器,不過現在已經棄用了。對於該類的介紹官網文檔已經有很詳細的解釋了,我就不再贅述了。
這章介紹的是scrapy中比較重要的一個類,希望本文會對小伙伴們有幫助,如果有疑問,歡迎在下面的評論區中提問。