日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Item详解

發(fā)布時間:2023/12/18 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Item详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文轉(zhuǎn)載自http://blog.csdn.net/sdulsj/article/details/52984619

Item是保存結(jié)構(gòu)數(shù)據(jù)的地方,Scrapy可以將解析結(jié)果以字典形式返回,但是Python中字典缺少結(jié)構(gòu),在大型爬蟲系統(tǒng)中很不方便。

Item提供了類字典的API,并且可以很方便的聲明字段,很多Scrapy組件可以利用Item的其他信息。

定義Item

定義Item非常簡單,只需要繼承scrapy.Item類,并將所有字段都定義為scrapy.Field類型即可

import scrapyclass Product(scrapy.Item):name = scrapy.Field()price = scrapy.Field()stock = scrapy.Field()last_updated = scrapy.Field(serializer=str)

Item Fields

Field對象可用來對每個字段指定元數(shù)據(jù)。例如上面last_updated的序列化函數(shù)指定為str,可任意指定元數(shù)據(jù),不過每種元數(shù)據(jù)對于不同的組件意義不一樣。

Item使用示例

你會看到Item的使用跟Python中的字典API非常類似

創(chuàng)建Item

>>> product = Product(name='Desktop PC', price=1000) >>> print product Product(name='Desktop PC', price=1000)

獲取值

>>> product['name'] Desktop PC >>> product.get('name') Desktop PC>>> product['price'] 1000>>> product['last_updated'] Traceback (most recent call last):... KeyError: 'last_updated'>>> product.get('last_updated', 'not set') not set>>> product['lala'] # getting unknown field Traceback (most recent call last):... KeyError: 'lala'>>> product.get('lala', 'unknown field') 'unknown field'>>> 'name' in product # is name field populated? True>>> 'last_updated' in product # is last_updated populated? False>>> 'last_updated' in product.fields # is last_updated a declared field? True>>> 'lala' in product.fields # is lala a declared field? False

設(shè)置值

>>> product['last_updated'] = 'today' >>> product['last_updated'] today>>> product['lala'] = 'test' # setting unknown field Traceback (most recent call last):... KeyError: 'Product does not support field: lala'

訪問所有的值

>>> product.keys() ['price', 'name']>>> product.items() [('price', 1000), ('name', 'Desktop PC')]

Item Loader

Item Loader為我們提供了生成Item的相當(dāng)便利的方法。Item為抓取的數(shù)據(jù)提供了容器,而Item Loader可以讓我們非常方便的將輸入填充到容器中。

下面我們通過一個例子來展示一般使用方法:

from scrapy.loader import ItemLoader from 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 valuesreturn l.load_item()

注意上面的name字段是從兩個xpath路徑添累加后得到。

輸入/輸出處理器

每個Item Loader對每個Field都有一個輸入處理器和一個輸出處理器。輸入處理器在數(shù)據(jù)被接受到時執(zhí)行,當(dāng)數(shù)據(jù)收集完后調(diào)用ItemLoader.load_item()時再執(zhí)行輸出處理器,返回最終結(jié)果。

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)

執(zhí)行流程是這樣的:

  • xpath1中的數(shù)據(jù)被提取出來,然后傳輸?shù)絥ame字段的輸入處理器中,在輸入處理器處理完后生成結(jié)果放在Item Loader里面(這時候沒有賦值給item)
  • xpath2數(shù)據(jù)被提取出來,然后傳輸給(1)中同樣的輸入處理器,因為它們都是name字段的處理器,然后處理結(jié)果被附加到(1)的結(jié)果后面
  • 跟2一樣
  • 跟3一樣,不過這次是直接的字面字符串值,先轉(zhuǎn)換成一個單元素的可迭代對象再傳給輸入處理器
  • 上面4步的數(shù)據(jù)被傳輸給name的輸出處理器,將最終的結(jié)果賦值給name字段
  • 自定義Item Loader

    使用類定義語法,下面是一個例子

    from scrapy.loader import ItemLoader from 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后綴來定義輸入和輸出處理器,并且還可以定義默認(rèn)的ItemLoader.default_input_processor和ItemLoader.default_input_processor.

    在Field定義中聲明輸入/輸出處理器

    還有個地方可以非常方便的添加輸入/輸出處理器,那就是直接在Field定義中

    import scrapy from scrapy.loader.processors import Join, MapCompose, TakeFirst from 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(),)

    優(yōu)先級:

  • 在Item Loader中定義的field_in和field_out
  • Filed元數(shù)據(jù)(input_processor和output_processor關(guān)鍵字)
  • Item Loader中的默認(rèn)的
  • Tips:一般來講,將輸入處理器定義在Item Loader的定義中field_in,然后將輸出處理器定義在Field元數(shù)據(jù)中

    Item Loader上下文

    Item Loader上下文被所有輸入/輸出處理器共享,比如你有一個解析長度的函數(shù)

    def parse_length(text, loader_context):unit = loader_context.get('unit', 'm')# ... length parsing code goes here ...return parsed_length

    初始化和修改上下文的值

    loader = ItemLoader(product) loader.context['unit'] = 'cm'loader = ItemLoader(product, unit='cm')class ProductLoader(ItemLoader):length_out = MapCompose(parse_length, unit='cm')

    內(nèi)置的處理器

  • Identity 啥也不做
  • TakeFirst 返回第一個非空值,通常用作輸出處理器
  • Join 將結(jié)果連起來,默認(rèn)使用空格’ ‘
  • Compose 將函數(shù)鏈接起來形成管道流,產(chǎn)生最后的輸出
  • MapCompose 跟上面的Compose類似,區(qū)別在于內(nèi)部結(jié)果在函數(shù)中的傳遞方式.它的輸入值是可迭代的,首先將第一個函數(shù)依次作用于所有值,產(chǎn)生新的可迭代輸入,作為第二個函數(shù)的輸入,最后生成的結(jié)果連起來返回最終值,一般用在輸入處理器中。
  • SelectJmes 使用json路徑來查詢值并返回結(jié)果
  • 總結(jié)

    以上是生活随笔為你收集整理的Item详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。