Python爬虫-Scrapy-CrawlSpider与ItemLoader
一、CrawlSpider
根據(jù)官方文檔可以了解到, 雖然對(duì)于特定的網(wǎng)頁(yè)來(lái)說(shuō)不一定是最好的選擇, 但是 CrwalSpider 是爬取規(guī)整的網(wǎng)頁(yè)時(shí)最常用的 spider, 而且有很好的可塑性.
除了繼承自 Spider 的屬性, 它還拓展了一些其他的屬性. 對(duì)我來(lái)說(shuō), 最常用的就是 rules 了.
爬蟲(chóng)一般來(lái)說(shuō)分為垂直爬取和水平爬取, 這里拿?貓眼電影TOP100?舉例. 垂直爬取就是從目錄進(jìn)入到內(nèi)容詳情后爬取, 即從當(dāng)前頁(yè)進(jìn)入某一影片的詳情頁(yè)面; 水平爬取就是從這一頁(yè)目錄翻到下一頁(yè)目錄后爬取, 即從當(dāng)前頁(yè)到排名第十一至二十的頁(yè)面. 不論是哪一種爬取, 都離不開(kāi) url, 即你想要去到的頁(yè)面的鏈接, 而 rules 就為我們提供了一套提取鏈接的規(guī)則, 以及得到鏈接后應(yīng)該怎么做.
來(lái)看一下 rules 中 Rule 的定義, class?scrapy.spiders.Rule(link_extractor,?callback=None,?cb_kwargs=None,?follow=None,?process_links=None,?process_request=None), 這里也只說(shuō)我自己經(jīng)常用到的.
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)
提取鏈接的規(guī)則在這里定義, 并且提取出鏈接后會(huì)生成一個(gè) scrapy.Request 對(duì)象. allow里是正則表達(dá)式, 過(guò)濾掉不符合要求的鏈接; restrict_xpath 和 restrict_css定義獲取鏈接的區(qū)域.
2. callback:
回調(diào)函數(shù), 請(qǐng)求得到相應(yīng)后用什么方法處理, 和 Request 中的 callback 一樣, 但是此處以字符串形式表示而不是方法引用.
3. follow:
請(qǐng)求得到響應(yīng)后是否繼續(xù)用本套rules規(guī)則來(lái)提取鏈接. 布爾值類(lèi)型, 如果callback為None, 則默認(rèn)為T(mén)rue, 否則為False.
這里的 rules 功能類(lèi)似于 Spider類(lèi)里的 parse() 方法, 請(qǐng)求 start_urls 中的鏈接, 并且返回新的 Request.
?
二、ItemLoader
Items 為抓取的數(shù)據(jù)提供了容器, 而 Item Loaders 提供填充容器的機(jī)制, 并且其API更加便捷好用.
之前用 Spider 類(lèi)的時(shí)候, 一般都是直接使用 scrapy.item 的, 當(dāng)網(wǎng)頁(yè)高度規(guī)整的時(shí)候我們改用了 CrawlSpider 類(lèi). 當(dāng)獲取到高度規(guī)整的數(shù)據(jù)時(shí), 我們想要進(jìn)行處理, 這時(shí)候 Item Loader 就發(fā)揮其作用了.
定義:? class scrapy.loader.ItemLoader(item=None, selector=None, response=None, parent=None, **context)
item:? 自己定義的容器.
selector:? Selector 對(duì)象, 提取填充數(shù)據(jù)的選擇器.
response:? Response 對(duì)象, 可以構(gòu)造選擇器的響應(yīng), 因?yàn)?scrapy 里的響應(yīng)可以直接使用 xpath 或 css, 這里把它當(dāng)成選擇器也差不多.
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 的字典類(lèi)使用方法, ItemLoader 顯得更簡(jiǎn)單明了, 這樣的代碼有著更好的可維護(hù)性以及自描述性.
這里有兩個(gè)小問(wèn)題特別說(shuō)一下, 是我自己剛開(kāi)始使用 ItemLoader 時(shí)犯的錯(cuò).
第一個(gè)就是, 使用 ItemLoader 后不需要調(diào)用 extract() 了, item里的值類(lèi)型為 list.
第二個(gè)就是, 當(dāng)頁(yè)面中有多個(gè) item, 循環(huán)遍歷時(shí)是使用 selector='你的選擇器'. 如果使用 response='你的響應(yīng)' 的話, 你會(huì)發(fā)現(xiàn)返回的 item 內(nèi)容要么出錯(cuò)要么重復(fù).
處理器:? 結(jié)合數(shù)據(jù)以及對(duì)數(shù)據(jù)進(jìn)行格式化和清洗的函數(shù)
例:
上圖中的 "unicode" 應(yīng)替換為 "str".
對(duì)我來(lái)說(shuō), 最常用就是 MapCompose 搭配匿名函數(shù), 可以更加靈活的處理數(shù)據(jù). MapCompose 和 Python 內(nèi)置的 map 類(lèi)似, 根據(jù)所給函數(shù)來(lái)遍歷處理可迭代對(duì)象中的每個(gè)值.
使用方法也挺簡(jiǎn)單, 只需要在編寫(xiě)填充機(jī)制的時(shí)候加上處理器即可, 如:??loader.add_css('tags', '.tag::text', MapCompose(str.title)).
定義 ItemLoader 的子類(lèi):
就我而言, 定義子類(lèi)最大的意義就是可以對(duì)每個(gè)已獲得的數(shù)據(jù)使用指定的處理器.
剛剛說(shuō)過(guò), ItemLoader 會(huì)對(duì) xpath 或 css 提取出來(lái)的結(jié)果做出類(lèi)似 extract() 的處理, 所以結(jié)果都會(huì)以列表的形式返回. 有時(shí)候列表里就一個(gè)以字符串形式表示的值, 我們希望直接得到字符串, 這時(shí)可以使用處理器 TakeFirst(), 返回列表第一個(gè)非空值, 類(lèi)似于 extract_first(). 如果所有的結(jié)果要做這樣的處理, 那在編寫(xiě)填充機(jī)制的時(shí)候依次添加處理器就顯得過(guò)于麻煩了. 此時(shí)我們就可以定義一個(gè) ItemLoader 的子類(lèi).?
通過(guò)重寫(xiě)?default_input_processor 和 default_input_processor 便可以達(dá)到目的.
例:
1 class NewLoader(ItemLoader): 2 default_input_processor = TakeFirst() 3 default_output_processor = str.title()需要注意的是處理器執(zhí)行的順序, 最先執(zhí)行編寫(xiě)填充機(jī)制時(shí)加的處理器, 接著是?default_input_processor, 然后是defualt_output_processor.
所有的處理在使用之前都需要導(dǎo)入.
?
以上便是我目前對(duì)?Scrapy 中 CrawlSpider 與 ItemLoader 的了解.
轉(zhuǎn)載于:https://www.cnblogs.com/yangshaolun/p/10886307.html
總結(jié)
以上是生活随笔為你收集整理的Python爬虫-Scrapy-CrawlSpider与ItemLoader的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 软件需求工程与UML建模——第九组第二周
- 下一篇: 【Rollo的Python之路】Scra