Item

抓取的主要目標是從非結構化源(一般是網頁)中提取結構化數據
ScrapySpider能夠以python字典的形式返回提取的數據,這很方便和熟悉
但python dicts缺少結構,很容易在字段名中輸入錯誤或返回不一致的數據,特別是在有許多spider的大型項目中

若要定義公共輸出數據格式,scrapy提供了Item類
Item對象是用於收集抓取的數據的簡單容器,它提供了一個相似於字典的API,該API語法方便簡潔,用於聲明可用字段

不少Scrapy的其餘組件會使用Item提供的抓取信息,如
  1) exporters會查看聲明的字段來肯定要導出的列
  2) 使用Item的字段元數據自定義序列化
  3) trackref會跟蹤Item實例以幫助查找內存泄漏

能夠爲每一個字段指明任何類型的元數據
Field 對象對接受的值沒有任何限制,所以文檔也沒法提供全部可用的元數據的鍵(key)參考列表
Field 對象中保存的每一個鍵能夠由多個組件使用,而且只有這些組件知道這個鍵的存在
可根據需求,定義使用其餘的 Field 鍵。
設置 Field 對象的主要目的就是在一個地方定義好全部的元數據。
通常來講,那些依賴某個字段的組件確定使用了特定的鍵(key),必須查看組件相關的文檔,查看其用了哪些元數據鍵(metadata key)python

 

  聲明Itemdjango

  聲明的scrapy項與django模型相似,只是scrapy項要簡單得多,由於沒有不一樣字段類型的概念scrapy

  Item對象
    class scrapy.item.Item([arg]) #經過指定可選的參數返回一個Item對象
    Item對象複製了標準的dict API,包括constructor,除了標準的dict API,額外提供的只有屬性fields
    該對象能夠理解爲一個字典,該字典包含了全部聲明的fields,包括設定過值和沒設定過值的fields
    其中,key就是Item對象裏定義的fields,values就是Item對象裏定義的Field對象

  Field對象
    class scrapy.item.Field([arg])
    Field類實際上就是內置的python字典類型,它不提供額外的屬性和方法ide

import scrapy

class Product(scrapy.Item):
    name = scrapy.Field()
    price = scrapy.Field()
    stock = scrapy.Field()
    last_updated = scrapy.Field(serializer=str)  #serializer就是字段last_updated的metadata key

 

  使用Itemspa

    product = Product(name='Desktop PC', price=1000)  #建立Item
    
    product['name']  #輸出:Desktop PC
    product['price']  #輸出:1000
    product['last_updated']  #報錯,not set
    
    product.get('name')  #輸出:Desktop PC
    product.get('last_updated')  #輸出:not set
    product.get('lala')  #報錯,沒有該key
    
    'name' in product  #輸出:True,判斷name是否設定了值
    'last_updated' in product  #輸出:False,判斷last_updated是否設定了值
    'last_updated' in product.fields  #輸出:True,判斷last_updated是否被聲明
    'lala' in product.fields  #輸出:False,判斷lala是否被聲明
    
    product['last_updated'] = 'today'  #設定值
    product['lala'] = 'test'  #報錯,lala字段沒有被聲明
    
    product.keys()  #輸出:['price', 'name']
    product.items()  #輸出:[('price', 1000), ('name', 'Desktop PC')]
    
    product2 = Product(product)   #複製product item
    product3 = product2.copy()   #複製product2 item
    
    dict(product)  #輸出:{'price': 1000, 'name': 'Desktop PC'},經過item複製dict
    Product({'name': 'Laptop PC', 'price': 1500})  #經過dict建立item

 

  擴展Itemcode

    class ExtendedProduct(Product):
        discount_percent = scrapy.Field(serializer=str)  #追加新的字段
        discount_expiration_date = scrapy.Field() #追加新的字段
        #修改既存字段,保持原來name字段的元數據不變,並追加了serializer metadata key
        name = scrapy.Field(Product.fields['name'], serializer=my_serializer)  
相關文章
相關標籤/搜索