Python爬虫-Scrapy-CrawlSpider与ItemLoader
一、CrawlSpider
根據官方文檔可以了解到, 雖然對于特定的網頁來說不一定是最好的選擇, 但是 CrwalSpider 是爬取規整的網頁時最常用的 spider, 而且有很好的可塑性.
除了繼承自 Spider 的屬性, 它還拓展了一些其他的屬性. 對我來說, 最常用的就是 rules 了.
爬蟲一般來說分為垂直爬取和水平爬取, 這里拿?貓眼電影TOP100?舉例. 垂直爬取就是從目錄進入到內容詳情后爬取, 即從當前頁進入某一影片的詳情頁面; 水平爬取就是從這一頁目錄翻到下一頁目錄后爬取, 即從當前頁到排名第十一至二十的頁面. 不論是哪一種爬取, 都離不開 url, 即你想要去到的頁面的鏈接, 而 rules 就為我們提供了一套提取鏈接的規則, 以及得到鏈接后應該怎么做.
來看一下 rules 中 Rule 的定義, class?scrapy.spiders.Rule(link_extractor,?callback=None,?cb_kwargs=None,?follow=None,?process_links=None,?process_request=None), 這里也只說我自己經常用到的.
1.? link_extractor:?
class scrapy.linkextractors.lxmlhtml.LxmlLinkExtractor(allow=(), deny=(), allow_domains=(), deny_domains=(), restrict_xpaths=(),?tags=('a', 'area'), attrs=('href',), canonicalize=False,?unique=True,
process_value=None, deny_extensions=None, restrict_css=(),?strip=True)
提取鏈接的規則在這里定義, 并且提取出鏈接后會生成一個 scrapy.Request 對象. allow里是正則表達式, 過濾掉不符合要求的鏈接; restrict_xpath 和 restrict_css定義獲取鏈接的區域.
2. callback:
回調函數, 請求得到相應后用什么方法處理, 和 Request 中的 callback 一樣, 但是此處以字符串形式表示而不是方法引用.
3. follow:
請求得到響應后是否繼續用本套rules規則來提取鏈接. 布爾值類型, 如果callback為None, 則默認為True, 否則為False.
這里的 rules 功能類似于 Spider類里的 parse() 方法, 請求 start_urls 中的鏈接, 并且返回新的 Request.
?
二、ItemLoader
Items 為抓取的數據提供了容器, 而 Item Loaders 提供填充容器的機制, 并且其API更加便捷好用.
之前用 Spider 類的時候, 一般都是直接使用 scrapy.item 的, 當網頁高度規整的時候我們改用了 CrawlSpider 類. 當獲取到高度規整的數據時, 我們想要進行處理, 這時候 Item Loader 就發揮其作用了.
定義:? class scrapy.loader.ItemLoader(item=None, selector=None, response=None, parent=None, **context)
item:? 自己定義的容器.
selector:? Selector 對象, 提取填充數據的選擇器.
response:? Response 對象, 可以構造選擇器的響應, 因為 scrapy 里的響應可以直接使用 xpath 或 css, 這里把它當成選擇器也差不多.
ItemLoader 的使用:
1 from scrapy.loader import ItemLoader 2 from qoutes.items import QuoteItem 3 import time 4 5 def parse_item(self, response): 6 quotes = response.css('.quote') 7 for quote in quotes: 8 loader = ItemLoader(item=QuoteItem(), selector=quote) 9 loader.add_css('author', '.author::text') 10 loader.add_css('tags', '.tag::text') 11 loader.add_xpath('text', './/*[@class="tag"]/text()') 12 loader.add_value('addtime', time.ctime()) 13 yield loader.load_item()相較于 Item 的字典類使用方法, ItemLoader 顯得更簡單明了, 這樣的代碼有著更好的可維護性以及自描述性.
這里有兩個小問題特別說一下, 是我自己剛開始使用 ItemLoader 時犯的錯.
第一個就是, 使用 ItemLoader 后不需要調用 extract() 了, item里的值類型為 list.
第二個就是, 當頁面中有多個 item, 循環遍歷時是使用 selector='你的選擇器'. 如果使用 response='你的響應' 的話, 你會發現返回的 item 內容要么出錯要么重復.
處理器:? 結合數據以及對數據進行格式化和清洗的函數
例:
上圖中的 "unicode" 應替換為 "str".
對我來說, 最常用就是 MapCompose 搭配匿名函數, 可以更加靈活的處理數據. MapCompose 和 Python 內置的 map 類似, 根據所給函數來遍歷處理可迭代對象中的每個值.
使用方法也挺簡單, 只需要在編寫填充機制的時候加上處理器即可, 如:??loader.add_css('tags', '.tag::text', MapCompose(str.title)).
定義 ItemLoader 的子類:
就我而言, 定義子類最大的意義就是可以對每個已獲得的數據使用指定的處理器.
剛剛說過, ItemLoader 會對 xpath 或 css 提取出來的結果做出類似 extract() 的處理, 所以結果都會以列表的形式返回. 有時候列表里就一個以字符串形式表示的值, 我們希望直接得到字符串, 這時可以使用處理器 TakeFirst(), 返回列表第一個非空值, 類似于 extract_first(). 如果所有的結果要做這樣的處理, 那在編寫填充機制的時候依次添加處理器就顯得過于麻煩了. 此時我們就可以定義一個 ItemLoader 的子類.?
通過重寫?default_input_processor 和 default_input_processor 便可以達到目的.
例:
1 class NewLoader(ItemLoader): 2 default_input_processor = TakeFirst() 3 default_output_processor = str.title()需要注意的是處理器執行的順序, 最先執行編寫填充機制時加的處理器, 接著是?default_input_processor, 然后是defualt_output_processor.
所有的處理在使用之前都需要導入.
?
以上便是我目前對?Scrapy 中 CrawlSpider 與 ItemLoader 的了解.
轉載于:https://www.cnblogs.com/yangshaolun/p/10886307.html
總結
以上是生活随笔為你收集整理的Python爬虫-Scrapy-CrawlSpider与ItemLoader的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件需求工程与UML建模——第九组第二周
- 下一篇: 小人大作战v0.02原型(单机)发布