国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

Scrapy爬蟲入門教程七

2019-11-06 06:11:08
字體:
供稿:網(wǎng)友

簡單的Python版本管理:pyenv Scrapy爬蟲入門教程一 Scrapy爬蟲入門教程二 Scrapy爬蟲入門教程三 Scrapy爬蟲入門教程四 Scrapy爬蟲入門教程五 Scrapy爬蟲入門教程六

項(xiàng)目加載器使用裝載機(jī)項(xiàng)目來填充的項(xiàng)目輸入和輸出處理器聲明項(xiàng)目加載器聲明輸入和輸出處理器項(xiàng)目加載器上下文ItemLoader對(duì)象ItemLoader 實(shí)例有以下方法ItemLoader 實(shí)例具有以下屬性嵌套裝載器重用和擴(kuò)展項(xiàng)目加載器可用內(nèi)置處理器

開發(fā)環(huán)境: Python 3.6.0 版本 (當(dāng)前最新) Scrapy 1.3.2 版本 (當(dāng)前最新)

項(xiàng)目加載器

項(xiàng)目加載器提供了一種方便的機(jī)制來填充抓取的項(xiàng)目。即使可以使用自己的類似字典的API填充項(xiàng)目,項(xiàng)目加載器提供了一個(gè)更方便的API,通過自動(dòng)化一些常見的任務(wù),如解析原始提取的數(shù)據(jù),然后分配它從剪貼過程中填充他們。

換句話說,Items提供了抓取數(shù)據(jù)的容器,而Item Loader提供了填充該容器的機(jī)制。

項(xiàng)目加載器旨在提供一種靈活,高效和容易的機(jī)制,通過爬蟲或源格式(HTML,xml等)擴(kuò)展和覆蓋不同的字段解析規(guī)則,而不會(huì)成為維護(hù)的噩夢(mèng)。

使用裝載機(jī)項(xiàng)目來填充的項(xiàng)目

要使用項(xiàng)目加載器,您必須首先實(shí)例化它。您可以使用類似dict的對(duì)象(例如Item或dict)實(shí)例化它,也可以不使用它,在這種情況下,項(xiàng)目將在Item Loader構(gòu)造函數(shù)中使用屬性中指定的Item類自動(dòng)ItemLoader.default_item_class 實(shí)例化。

然后,您開始收集值到項(xiàng)裝載程序,通常使用選擇器。您可以向同一項(xiàng)目字段添加多個(gè)值; 項(xiàng)目加載器將知道如何使用適當(dāng)?shù)奶幚砗瘮?shù)“加入”這些值。

這里是Spider中典型的Item Loader用法,使用Items部分中聲明的PRoduct項(xiàng):

from scrapy.loader import ItemLoaderfrom myproject.items import Productdef parse(self, response): l = ItemLoader(item=Product(), response=response) l.add_xpath('name', '//div[@class="product_name"]') l.add_xpath('name', '//div[@class="product_title"]') l.add_xpath('price', '//p[@id="price"]') l.add_CSS('stock', 'p#stock]') l.add_value('last_updated', 'today') # you can also use literal values return l.load_item()

通過快速查看該代碼,我們可以看到該name字段正從頁面中兩個(gè)不同的XPath位置提?。?/p>//div[@class="product_name"]//div[@class="product_title"] 換句話說,通過使用add_xpath()方法從兩個(gè)XPath位置提取數(shù)據(jù)來收集數(shù)據(jù)。這是稍后將分配給name字段的數(shù)據(jù)。

之后,類似的調(diào)用用于pricestock字段(后者使用帶有add_css()方法的CSS選擇器),最后使用不同的方法last_update直接使用文字值(today)填充字段add_value()。

最后,收集的所有數(shù)據(jù)時(shí),該ItemLoader.load_item()方法被稱為實(shí)際上返回填充先前提取并與收集到的數(shù)據(jù)的項(xiàng)目add_xpath(), add_css()add_value()調(diào)用。

輸入和輸出處理器

項(xiàng)目加載器對(duì)于每個(gè)(項(xiàng)目)字段包含一個(gè)輸入處理器和一個(gè)輸出處理器。輸入處理器只要它的接收處理所提取的數(shù)據(jù)(通過add_xpath(),add_css()或 add_value()方法)和輸入處理器的結(jié)果被收集并保持ItemLoader內(nèi)部。收集所有數(shù)據(jù)后,ItemLoader.load_item()調(diào)用該 方法來填充和獲取填充 Item對(duì)象。這是當(dāng)輸出處理器使用先前收集的數(shù)據(jù)(并使用輸入處理器處理)調(diào)用時(shí)。輸出處理器的結(jié)果是分配給項(xiàng)目的最終值。

讓我們看一個(gè)例子來說明如何為特定字段調(diào)用輸入和輸出處理器(同樣適用于任何其他字段):

l = ItemLoader(Product(), some_selector)l.add_xpath('name', xpath1) # (1)l.add_xpath('name', xpath2) # (2)l.add_css('name', css) # (3)l.add_value('name', 'test') # (4)return l.load_item() # (5)

所以會(huì)發(fā)生什么:

從數(shù)據(jù)xpath1提取出來,并通過所傳遞的輸入處理器的的name字段。輸入處理器的結(jié)果被收集并保存在項(xiàng)目加載器中(但尚未分配給項(xiàng)目)。從中xpath2提取數(shù)據(jù),并通過(1)中使用的同一輸入處理器。輸入處理器的結(jié)果附加到(1)中收集的數(shù)據(jù)(如果有)。這種情況類似于先前的情況,除了數(shù)據(jù)從cssCSS選擇器提取,并且通過在(1)和(2)中使用的相同的輸入處理器。輸入處理器的結(jié)果附加到在(1)和(2)中收集的數(shù)據(jù)(如果有的話)。這種情況也與之前的類似,除了要收集的值直接分配,而不是從XPath表達(dá)式或CSS選擇器中提取。但是,該值仍然通過輸入處理器。在這種情況下,由于該值不可迭代,因此在將其傳遞給輸入處理器之前,它將轉(zhuǎn)換為單個(gè)元素的可迭代,因?yàn)檩斎胩幚砥骺偸墙邮盏?。在步驟(1),(2),(3)和(4)中收集的數(shù)據(jù)通過name字段的輸出處理器。輸出處理器的結(jié)果是分配給name 項(xiàng)目中字段的值。

值得注意的是,處理器只是可調(diào)用對(duì)象,它們使用要解析的數(shù)據(jù)調(diào)用,并返回解析的值。所以你可以使用任何功能作為輸入或輸出處理器。唯一的要求是它們必須接受一個(gè)(也只有一個(gè))位置參數(shù),這將是一個(gè)迭代器。

注意

輸入和輸出處理器都必須接收一個(gè)迭代器作為它們的第一個(gè)參數(shù)。這些函數(shù)的輸出可以是任何東西。輸入處理器的結(jié)果將附加到包含收集的值(對(duì)于該字段)的內(nèi)部列表(在加載程序中)。輸出處理器的結(jié)果是最終分配給項(xiàng)目的值。

另一件需要記住的事情是,輸入處理器返回的值在內(nèi)部(在列表中)收集,然后傳遞到輸出處理器以填充字段。

最后,但并非最不重要的是,Scrapy自帶一些常用的處理器內(nèi)置的方便。

聲明項(xiàng)目加載器

項(xiàng)目加載器通過使用類定義語法聲明為Items。這里是一個(gè)例子:

from scrapy.loader import ItemLoaderfrom scrapy.loader.processors import TakeFirst, MapCompose, Joinclass ProductLoader(ItemLoader): default_output_processor = TakeFirst() name_in = MapCompose(unicode.title) name_out = Join() price_in = MapCompose(unicode.strip) # ...

可以看到,輸入處理器使用_in后綴聲明,而輸出處理器使用_out后綴聲明。您還可以使用ItemLoader.default_input_processor和 ItemLoader.default_output_processor屬性聲明默認(rèn)輸入/輸出 處理器。

聲明輸入和輸出處理器

如上一節(jié)所述,輸入和輸出處理器可以在Item Loader定義中聲明,這種方式聲明輸入處理器是很常見的。但是,還有一個(gè)地方可以指定要使用的輸入和輸出處理器:在項(xiàng)目字段 元數(shù)據(jù)中。這里是一個(gè)例子:

import scrapyfrom scrapy.loader.processors import Join, MapCompose, TakeFirstfrom w3lib.html import remove_tagsdef filter_price(value): if value.isdigit(): return valueclass Product(scrapy.Item): name = scrapy.Field( input_processor=MapCompose(remove_tags), output_processor=Join(), ) price = scrapy.Field( input_processor=MapCompose(remove_tags, filter_price), output_processor=TakeFirst(), )>>> from scrapy.loader import ItemLoader>>> il = ItemLoader(item=Product())>>> il.add_value('name', [u'Welcome to my', u'<strong>website</strong>'])>>> il.add_value('price', [u'&euro;', u'<span>1000</span>'])>>> il.load_item(){'name': u'Welcome to my website', 'price': u'1000'}

輸入和輸出處理器的優(yōu)先級(jí)順序如下:

項(xiàng)目加載程序字段特定屬性:field_in和field_out(最高優(yōu)先級(jí))字段元數(shù)據(jù)(input_processor和output_processor鍵)項(xiàng)目加載器默認(rèn)值:ItemLoader.default_input_processor()和 ItemLoader.default_output_processor()(最低優(yōu)先級(jí))

參見:重用和擴(kuò)展項(xiàng)目加載器。

項(xiàng)目加載器上下文

項(xiàng)目加載器上下文是在項(xiàng)目加載器中的所有輸入和輸出處理器之間共享的任意鍵/值的dict。它可以在聲明,實(shí)例化或使用Item Loader時(shí)傳遞。它們用于修改輸入/輸出處理器的行為。

例如,假設(shè)您有一個(gè)parse_length接收文本值并從中提取長度的函數(shù):

def parse_length (text , loader_context ): unit = loader_context 。get ('unit' , 'm' ) #...長度解析代碼在這里... return parsed_length

通過接受一個(gè)loader_context參數(shù),該函數(shù)顯式地告訴Item Loader它能夠接收一個(gè)Item Loader上下文,因此Item Loader在調(diào)用它時(shí)傳遞當(dāng)前活動(dòng)的上下文,因此處理器功能(parse_length在這種情況下)可以使用它們。

有幾種方法可以修改Item Loader上下文值:

通過修改當(dāng)前活動(dòng)的Item Loader上下文(context屬性):

loader = ItemLoader(product)loader.context['unit'] = 'cm'

On Item Loader實(shí)例化(Item Loader構(gòu)造函數(shù)的關(guān)鍵字參數(shù)存儲(chǔ)在Item Loader上下文中):

loader = ItemLoader(product, unit='cm')

On Item Loader聲明,對(duì)于那些支持使用Item Loader上下文實(shí)例化的輸入/輸出處理器。MapCompose是其中之一:

class ProductLoader(ItemLoader): length_out = MapCompose(parse_length, unit='cm')

ItemLoader對(duì)象

class scrapy.loader.ItemLoader([item, selector, response, ]**kwargs)

返回一個(gè)新的Item Loader來填充給定的Item。如果沒有給出項(xiàng)目,則使用中的類自動(dòng)實(shí)例化 default_item_class。

當(dāng)使用選擇器或響應(yīng)參數(shù)實(shí)例化時(shí),ItemLoader類提供了使用選擇器從網(wǎng)頁提取數(shù)據(jù)的方便的機(jī)制。

參數(shù):

item(Item對(duì)象)-項(xiàng)目實(shí)例來填充用以后調(diào)用 add_xpath(),add_css()或add_value()。selector(Selectorobject) - 當(dāng)使用add_xpath()(或。add_css())或replace_xpath() (或replace_css())方法時(shí),從中提取數(shù)據(jù)的選擇器 。response(ResponSEObject) - 用于使用構(gòu)造選擇器的響應(yīng) default_selector_class,除非給出選擇器參數(shù),在這種情況下,將忽略此參數(shù)。 項(xiàng)目,選擇器,響應(yīng)和剩余的關(guān)鍵字參數(shù)被分配給Loader上下文(可通過context屬性訪問)。

ItemLoader 實(shí)例有以下方法:

get_value(value,* processors,** kwargs ) 處理給定value的給定processors和關(guān)鍵字參數(shù)。

可用的關(guān)鍵字參數(shù):

參數(shù): re(str 或compiled regex) 一個(gè)正則表達(dá)式extract_regex(),用于使用方法從給定值提取數(shù)據(jù),在處理器之前應(yīng)用 例子:

>>> from scrapy.loader.processors import TakeFirst>>> loader.get_value(u'name: foo', TakeFirst(), unicode.upper, re='name: (.+)')'FOO`

add_value(field_name,value,* processors,** kwargs ) 處理,然后添加給value定字段的給定。

該值首先通過get_value()賦予 processors和kwargs,然后通過 字段輸入處理器及其結(jié)果追加到為該字段收集的數(shù)據(jù)。如果字段已包含收集的數(shù)據(jù),則會(huì)添加新數(shù)據(jù)。

給定field_name可以是None,在這種情況下可以添加多個(gè)字段的值。并且已處理的值應(yīng)為一個(gè)字段,其中field_name映射到值。

例子:

loader.add_value('name', u'Color TV')loader.add_value('colours', [u'white', u'blue'])loader.add_value('length', u'100')loader.add_value('name', u'name: foo', TakeFirst(), re='name: (.+)')loader.add_value(None, {'name': u'foo', 'sex': u'male'})

replace_value(field_name,value,* processors,** kwargs ) 類似于add_value()但是用新值替換收集的數(shù)據(jù),而不是添加它。

get_xpath(xpath,* processors,** kwargs ) 類似于ItemLoader.get_value()但接收XPath而不是值,用于從與此相關(guān)聯(lián)的選擇器提取unicode字符串的列表ItemLoader。

參數(shù):

xpath(str) - 從中??提取數(shù)據(jù)的XPathre(str 或compiled regex) - 用于從所選XPath區(qū)域提取數(shù)據(jù)的正則表達(dá)式 例子:# HTML snippet: <p class="product-name">Color TV</p>loader.get_xpath('//p[@class="product-name"]')# HTML snippet: <p id="price">the price is $1200</p>loader.get_xpath('//p[@id="price"]', TakeFirst(), re='the price is (.*)')

add_xpath(field_name,xpath,* processor,** kwargs ) 類似于ItemLoader.add_value()但接收XPath而不是值,用于從與此相關(guān)聯(lián)的選擇器提取unicode字符串的列表ItemLoader。

見get_xpath()的kwargs。

參數(shù): xpath(str) - 從中??提取數(shù)據(jù)的XPath

例子:

# HTML snippet: <p class="product-name">Color TV</p>loader.add_xpath('name', '//p[@class="product-name"]')# HTML snippet: <p id="price">the price is $1200</p>loader.add_xpath('price', '//p[@id="price"]', re='the price is (.*)')

replace_xpath(field_name,xpath,* processor,** kwargs ) 類似于add_xpath()但替換收集的數(shù)據(jù),而不是添加它。

get_css(css,* processors,** kwargs ) 類似于ItemLoader.get_value()但接收一個(gè)CSS選擇器而不是一個(gè)值,用于從與此相關(guān)的選擇器提取一個(gè)unicode字符串列表ItemLoader。

參數(shù):

css(str) - 從中??提取數(shù)據(jù)的CSS選擇器re(str 或compiled regex) - 用于從所選CSS區(qū)域提取數(shù)據(jù)的正則表達(dá)式 例子:# HTML snippet: <p class="product-name">Color TV</p>loader.get_css('p.product-name')# HTML snippet: <p id="price">the price is $1200</p>loader.get_css('p#price', TakeFirst(), re='the price is (.*)')

add_css(field_name,css,* processors,** kwargs ) 類似于ItemLoader.add_value()但接收一個(gè)CSS選擇器而不是一個(gè)值,用于從與此相關(guān)的選擇器提取一個(gè)unicode字符串列表ItemLoader。

見get_css()的kwargs。

參數(shù): css(str) - 從中??提取數(shù)據(jù)的CSS選擇器 例子:

# HTML snippet: <p class="product-name">Color TV</p>loader.add_css('name', 'p.product-name')# HTML snippet: <p id="price">the price is $1200</p>loader.add_css('price', 'p#price', re='the price is (.*)')

replace_css(field_name,css,* processors,** kwargs ) 類似于add_css()但替換收集的數(shù)據(jù),而不是添加它。

load_item() 使用目前收集的數(shù)據(jù)填充項(xiàng)目,并返回。收集的數(shù)據(jù)首先通過輸出處理器,以獲得要分配給每個(gè)項(xiàng)目字段的最終值。

nested_xpath(xpath ) 使用xpath選擇器創(chuàng)建嵌套加載器。所提供的選擇器應(yīng)用于與此相關(guān)的選擇器ItemLoader。嵌套裝載機(jī)股份Item 與母公司ItemLoader這么調(diào)用add_xpath(), add_value(),replace_value()等會(huì)像預(yù)期的那樣。

nested_css(css ) 使用css選擇器創(chuàng)建嵌套加載器。所提供的選擇器應(yīng)用于與此相關(guān)的選擇器ItemLoader。嵌套裝載機(jī)股份Item 與母公司ItemLoader這么調(diào)用add_xpath(), add_value(),replace_value()等會(huì)像預(yù)期的那樣。

get_collected_values(field_name ) 返回給定字段的收集值。

get_output_value(field_name ) 返回給定字段使用輸出處理器解析的收集值。此方法根本不填充或修改項(xiàng)目。

get_input_processor(field_name ) 返回給定字段的輸入處理器。

get_output_processor(field_name ) 返回給定字段的輸出處理器。

ItemLoader 實(shí)例具有以下屬性:

item Item此項(xiàng)目加載器解析的對(duì)象。

context 此項(xiàng)目Loader 的當(dāng)前活動(dòng)上下文。

default_item_class Item類(或工廠),用于在構(gòu)造函數(shù)中未給出時(shí)實(shí)例化項(xiàng)。

default_input_processor 用于不指定一個(gè)字段的字段的默認(rèn)輸入處理器。

default_output_processor 用于不指定一個(gè)字段的字段的默認(rèn)輸出處理器。

default_selector_class 所使用的類構(gòu)造selector的此 ItemLoader,如果只響應(yīng)在構(gòu)造函數(shù)給出。如果在構(gòu)造函數(shù)中給出了選擇器,則忽略此屬性。此屬性有時(shí)在子類中被覆蓋。

selector Selector從中提取數(shù)據(jù)的對(duì)象。它是在構(gòu)造函數(shù)中給出的選擇器,或者是從構(gòu)造函數(shù)中使用的給定的響應(yīng)創(chuàng)建的 default_selector_class。此屬性意味著是只讀的。

嵌套裝載器

當(dāng)解析來自文檔的子部分的相關(guān)值時(shí),創(chuàng)建嵌套加載器可能是有用的。假設(shè)您從頁面的頁腳中提取細(xì)節(jié),看起來像:

例:

<footer> <a class="social" >Like Us</a> <a class="social" >Follow Us</a> <a class="email" href="mailto:whatever@example.com">Email Us</a></footer>

如果沒有嵌套加載器,則需要為要提取的每個(gè)值指定完整的xpath(或css)。

例:

loader = ItemLoader(item=Item())# load stuff not in the footerloader.add_xpath('social', '//footer/a[@class = "social"]/@href')loader.add_xpath('email', '//footer/a[@class = "email"]/@href')loader.load_item()

相反,您可以使用頁腳選擇器創(chuàng)建嵌套加載器,并相對(duì)于頁腳添加值。功能是相同的,但您避免重復(fù)頁腳選擇器。

例:

loader = ItemLoader(item=Item())# load stuff not in the footerfooter_loader = loader.nested_xpath('//footer')footer_loader.add_xpath('social', 'a[@class = "social"]/@href')footer_loader.add_xpath('email', 'a[@class = "email"]/@href')# no need to call footer_loader.load_item()loader.load_item()

您可以任意嵌套加載器,并且可以使用xpath或css選擇器。作為一般的指導(dǎo)原則,當(dāng)他們使你的代碼更簡單,但不要超越嵌套或使用解析器可能變得難以閱讀使用嵌套加載程序。

重用和擴(kuò)展項(xiàng)目加載器

隨著你的項(xiàng)目越來越大,越來越多的爬蟲,維護(hù)成為一個(gè)根本的問題,特別是當(dāng)你必須處理每個(gè)爬蟲的許多不同的解析規(guī)則,有很多異常,但也想重用公共處理器。

項(xiàng)目加載器旨在減輕解析規(guī)則的維護(hù)負(fù)擔(dān),同時(shí)不會(huì)失去靈活性,同時(shí)提供了擴(kuò)展和覆蓋它們的方便的機(jī)制。因此,項(xiàng)目加載器支持傳統(tǒng)的Python類繼承,以處理特定爬蟲(或爬蟲組)的差異。

例如,假設(shè)某個(gè)特定站點(diǎn)以三個(gè)短劃線(例如)包含其產(chǎn)品名稱,并且您不希望最終在最終產(chǎn)品名稱中刪除那些破折號(hào)?!狿lasma TV—

以下是如何通過重用和擴(kuò)展默認(rèn)產(chǎn)品項(xiàng)目Loader(ProductLoader)來刪除這些破折號(hào):

from scrapy.loader.processors import MapComposefrom myproject.ItemLoaders import ProductLoaderdef strip_dashes(x): return x.strip('-')class SiteSpecificLoader(ProductLoader): name_in = MapCompose(strip_dashes, ProductLoader.name_in)

另一種擴(kuò)展項(xiàng)目加載器可能非常有用的情況是,當(dāng)您有多種源格式,例如XML和HTML。在XML版本中,您可能想要?jiǎng)h除CDATA事件。下面是一個(gè)如何做的例子:

from scrapy.loader.processors import MapComposefrom myproject.ItemLoaders import ProductLoaderfrom myproject.utils.xml import remove_cdataclass XmlProductLoader(ProductLoader): name_in = MapCompose(remove_cdata, ProductLoader.name_in)

這就是你通常擴(kuò)展輸入處理器的方式。

對(duì)于輸出處理器,更常見的是在字段元數(shù)據(jù)中聲明它們,因?yàn)樗鼈兺ǔH依賴于字段而不是每個(gè)特定站點(diǎn)解析規(guī)則(如輸入處理器)。另請(qǐng)參見: 聲明輸入和輸出處理器。

還有許多其他可能的方法來擴(kuò)展,繼承和覆蓋您的項(xiàng)目加載器,不同的項(xiàng)目加載器層次結(jié)構(gòu)可能更適合不同的項(xiàng)目。Scrapy只提供了機(jī)制; 它不強(qiáng)加任何特定的組織你的Loader集合 - 這取決于你和你的項(xiàng)目的需要。

可用內(nèi)置處理器

即使您可以使用任何可調(diào)用函數(shù)作為輸入和輸出處理器,Scrapy也提供了一些常用的處理器,如下所述。其中一些,像MapCompose(通常用作輸入處理器)組成按順序執(zhí)行的幾個(gè)函數(shù)的輸出,以產(chǎn)生最終的解析值。

下面是所有內(nèi)置處理器的列表:

class scrapy.loader.processors.Identity

最簡單的處理器,什么都不做。它返回原始值不變。它不接收任何構(gòu)造函數(shù)參數(shù),也不接受Loader上下文。

例:

>>> from scrapy.loader.processors import Identity>>> proc = Identity()>>> proc(['one', 'two', 'three'])['one', 'two', 'three']

class scrapy.loader.processors.TakeFirst

從接收到的值中返回第一個(gè)非空值/非空值,因此它通常用作單值字段的輸出處理器。它不接收任何構(gòu)造函數(shù)參數(shù),也不接受Loader上下文。

例:

>>> from scrapy.loader.processors import TakeFirst>>> proc = TakeFirst()>>> proc(['', 'one', 'two', 'three'])'one'

class scrapy.loader.processors.Join(separator=u' ')

返回與構(gòu)造函數(shù)中給定的分隔符聯(lián)接的值,默認(rèn)為。它不接受加載器上下文。u’ ‘

當(dāng)使用默認(rèn)分隔符時(shí),此處理器相當(dāng)于以下功能: u’ ‘.join

例子:

>>> from scrapy.loader.processors import Join>>> proc = Join()>>> proc(['one', 'two', 'three'])u'one two three'>>> proc = Join('<br>')>>> proc(['one', 'two', 'three'])u'one<br>two<br>three'

class scrapy.loader.processors.Compose(*functions, **default_loader_context)

由給定函數(shù)的組合構(gòu)成的處理器。這意味著該處理器的每個(gè)輸入值都被傳遞給第一個(gè)函數(shù),并且該函數(shù)的結(jié)果被傳遞給第二個(gè)函數(shù),依此類推,直到最后一個(gè)函數(shù)返回該處理器的輸出值。

默認(rèn)情況下,停止進(jìn)程N(yùn)one值。可以通過傳遞關(guān)鍵字參數(shù)來更改此行為stop_on_none=False。

例:

>>> from scrapy.loader.processors import Compose>>> proc = Compose(lambda v: v[0], str.upper)>>> proc(['hello', 'world'])'HELLO'

每個(gè)功能可以可選地接收loader_context參數(shù)。對(duì)于那些處理器,這個(gè)處理器將通過該參數(shù)傳遞當(dāng)前活動(dòng)的Loader上下文。

在構(gòu)造函數(shù)中傳遞的關(guān)鍵字參數(shù)用作傳遞給每個(gè)函數(shù)調(diào)用的默認(rèn)Loader上下文值。但是,傳遞給函數(shù)的最后一個(gè)Loader上下文值將被當(dāng)前可用該屬性訪問的當(dāng)前活動(dòng)Loader上下文ItemLoader.context() 覆蓋。

class scrapy.loader.processors.MapCompose(*functions, **default_loader_context)

與處理器類似,由給定功能的組成構(gòu)成的Compose處理器。與此處理器的區(qū)別在于內(nèi)部結(jié)果在函數(shù)之間傳遞的方式,如下所示:

該處理器的輸入值被迭代,并且第一函數(shù)被應(yīng)用于每個(gè)元素。這些函數(shù)調(diào)用的結(jié)果(每個(gè)元素一個(gè))被連接以構(gòu)造新的迭代,然后用于應(yīng)用??第二個(gè)函數(shù),等等,直到最后一個(gè)函數(shù)被應(yīng)用于收集的值列表的每個(gè)值遠(yuǎn)。最后一個(gè)函數(shù)的輸出值被連接在一起以產(chǎn)生該處理器的輸出。

每個(gè)特定函數(shù)可以返回值或值列表,這些值通過應(yīng)用于其他輸入值的相同函數(shù)返回的值列表展平。函數(shù)也可以返回None,在這種情況下,該函數(shù)的輸出將被忽略,以便在鏈上進(jìn)行進(jìn)一步處理。

此處理器提供了一種方便的方法來組合只使用單個(gè)值(而不是iterables)的函數(shù)。由于這個(gè)原因, MapCompose處理器通常用作輸入處理器,因?yàn)閿?shù)據(jù)通常使用選擇器的 extract()方法提取,選擇器返回unicode字符串的列表。

下面的例子應(yīng)該說明它是如何工作的:

>>> def filter_world(x):... return None if x == 'world' else x...>>> from scrapy.loader.processors import MapCompose>>> proc = MapCompose(filter_world, unicode.upper)>>> proc([u'hello', u'world', u'this', u'is', u'scrapy'])[u'HELLO, u'THIS', u'IS', u'SCRAPY']

與Compose處理器一樣,函數(shù)可以接收Loader上下文,并且構(gòu)造函數(shù)關(guān)鍵字參數(shù)用作默認(rèn)上下文值。有關(guān)Compose更多信息,請(qǐng)參閱 處理器。

class scrapy.loader.processors.SelectJmes(json_path)

使用提供給構(gòu)造函數(shù)的json路徑查詢值,并返回輸出。需要運(yùn)行jmespath(https://github.com/jmespath/jmespath.py)。該處理器一次只需要一個(gè)輸入。

例:

>>> from scrapy.loader.processors import SelectJmes, Compose, MapCompose>>> proc = SelectJmes("foo") #for direct use on lists and dictionaries>>> proc({'foo': 'bar'})'bar'>>> proc({'foo': {'bar': 'baz'}}){'bar': 'baz'}

使用Json:

>>> import json>>> proc_single_json_str = Compose(json.loads, SelectJmes("foo"))>>> proc_single_json_str('{"foo": "bar"}')u'bar'>>> proc_json_list = Compose(json.loads, MapCompose(SelectJmes('foo')))>>> proc_json_list('[{"foo":"bar"}, {"baz":"tar"}]')[u'bar']
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 雅安市| 襄樊市| 小金县| 高邮市| 图木舒克市| 睢宁县| 姜堰市| 手游| 景洪市| 顺昌县| 沂南县| 离岛区| 仪陇县| 思茅市| 拜城县| 茶陵县| 金湖县| 赤壁市| 沙田区| 廊坊市| 四平市| 乌兰浩特市| 崇礼县| 永吉县| 关岭| 普兰店市| 佳木斯市| 抚州市| 二手房| 宜宾县| 扎赉特旗| 临桂县| 白山市| 光泽县| 剑河县| 临猗县| 武山县| 苏尼特右旗| 鄂托克前旗| 泰来县| 麦盖提县|