Items
爬取的主要目標就是從非結構性的數據源提取結構性數據,比如網頁。 Scrapy提供 Item 類來滿足這種需求。
Item 對象是種簡單的容器。保存了爬取到得數據。 其提供了 類似於詞典(dictionary-like) 的API以及用於聲明可用字段的簡單語法。
聲明Item
Item使用簡單的class定義語法以及 Field 對象來聲明。
比如:
import scrapy
class Product(scrapy.Item):
name = scrapy.Field()
price = scrapy.Field()
stock = scrapy.Field()
last_updated = scrapy.Field(serializer=str)
注解
熟悉 Django 的朋友一定會注意到Scrapy Item定義方式與 Django Models 非常類似, 只是沒有那么多不同的字段類型(Field type),更為簡單。
Item字段(Item Fields)
Field 對象指明了每一個字段的元數據(metadata)。比如以下樣例中 last_updated 中指明了該字段的序列化函數。
您能夠為每一個字段指明不論什么類型的元數據。 Field 對象對接受的值沒有不論什么限制。也正是由於這個原因,文檔也無法提供全部可用的元數據的鍵(key)參考列表。
Field 對象中保存的每一個鍵能夠由多個組件使用,而且僅僅有這些組件知道這個鍵的存在。您能夠依據自己的需求,定義使用其它的Field 鍵。 設置 Field 對象的主要目的就是在一個地方定義好全部的元數據。
一般來說,那些依賴某個字段的組件肯定使用了特定的鍵(key)。您必須查看組件相關的文檔,查看其用了哪些元數據鍵(metadata key)。
須要注意的是。用來聲明item的 Field 對象並沒有被賦值為class的屬性。 只是您能夠通過Item.fields 屬性進行訪問。
以上就是全部您須要知道的怎樣聲明item的內容了。
與Item配合
接下來以 下邊聲明 的 Product item來演示一些item的操作。您會發現API和 dict API 很相似。
創建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
設置字段的值
>>> 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'
獲取全部獲取到的值
您能夠使用 dict API 來獲取全部的值:
>>> product.keys()
['price', 'name']
>>> product.items()
[('price', 1000), ('name', 'Desktop PC')]
其它任務
復制item:
>>> product2 = Product(product)
>>> print product2
Product(name='Desktop PC', price=1000)
>>> product3 = product2.copy()
>>> print product3
Product(name='Desktop PC', price=1000)
依據item創建字典(dict):
>>> dict(product) # create a dict from all populated values
{'price': 1000, 'name': 'Desktop PC'}
依據字典(dict)創建item:
>>> Product({'name': 'Laptop PC', 'price': 1500})
Product(price=1500, name='Laptop PC')
>>> Product({'name': 'Laptop PC', 'lala': 1500}) # warning: unknown field in dict
Traceback (most recent call last):
...
KeyError: 'Product does not support field: lala'
擴展Item
您能夠通過繼承原始的Item來擴展item(加入很多其它的字段或者改動某些字段的元數據)。
比如:
class DiscountedProduct(Product):
discount_percent = scrapy.Field(serializer=str)
discount_expiration_date = scrapy.Field()
您也能夠通過使用原字段的元數據,加入新的值或改動原來的值來擴展字段的元數據:
class SpecificProduct(Product):
name = scrapy.Field(Product.fields['name'], serializer=my_serializer)
這段代碼在保留全部原來的元數據值的情況下加入(或者覆蓋)了 name 字段的 serializer 。