鍍金池/ 教程/ Python/ Items
Benchmarking
命令行工具(Command line tools)
下載器中間件(Downloader Middleware)
信號(hào)(Signals)
Telnet 終端(Telnet Console)
初窺 Scrapy
數(shù)據(jù)收集(Stats Collection)
Scrapyd
通用爬蟲(Broad Crawls)
Item Loaders
試驗(yàn)階段特性
Scrapy 入門教程
自動(dòng)限速(AutoThrottle)擴(kuò)展
Settings
Scrapy 終端(Scrapy shell)
下載項(xiàng)目圖片
DjangoItem
調(diào)試(Debugging)Spiders
選擇器(Selectors)
Feed exports
Spiders Contracts
借助 Firefox 來爬取
Logging
Spiders
Ubuntu 軟件包
實(shí)踐經(jīng)驗(yàn)(Common Practices)
安裝指南
Item Exporters
擴(kuò)展(Extensions)
Items
Spider 中間件(Middleware)
異常(Exceptions)
例子
發(fā)送 email
架構(gòu)概覽
常見問題(FAQ)
Jobs:暫停,恢復(fù)爬蟲
核心 API
使用 Firebug 進(jìn)行爬取
Item Pipeline
Link Extractors
Web Service
調(diào)試內(nèi)存溢出

Items

爬取的主要目標(biāo)就是從非結(jié)構(gòu)性的數(shù)據(jù)源提取結(jié)構(gòu)性數(shù)據(jù),例如網(wǎng)頁。Scrapy 提供 Item 類來滿足這樣的需求。

Item 對象是種簡單的容器,保存了爬取到得數(shù)據(jù)。其提供了類似于詞典(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 的朋友一定會(huì)注意到 Scrapy Item 定義方式與 Django Models 很類似, 不過沒有那么多不同的字段類型(Field type),更為簡單。

Item字段(Item Fields)

Field 對象指明了每個(gè)字段的元數(shù)據(jù)(metadata)。例如下面例子中 last_updated 中指明了該字段的序列化函數(shù)。

您可以為每個(gè)字段指明任何類型的元數(shù)據(jù)。Field 對象對接受的值沒有任何限制。也正是因?yàn)檫@個(gè)原因,文檔也無法提供所有可用的元數(shù)據(jù)的鍵(key)參考列表。Field 對象中保存的每個(gè)鍵可以由多個(gè)組件使用,并且只有這些組件知道這個(gè)鍵的存在。您可以根據(jù)自己的需求,定義使用其他的 Field 鍵。 設(shè)置 Field 對象的主要目的就是在一個(gè)地方定義好所有的元數(shù)據(jù)。一般來說,那些依賴某個(gè)字段的組件肯定使用了特定的鍵(key)。您必須查看組件相關(guān)的文檔,查看其用了哪些元數(shù)據(jù)鍵(metadata key)。

需要注意的是,用來聲明 item 的 Field 對象并沒有被賦值為 class 的屬性。不過您可以通過 Item.fields 屬性進(jìn)行訪問。

以上就是所有您需要知道的如何聲明 item 的內(nèi)容了。

與 Item 配合

接下來以下邊聲明的 Product item 來演示一些 item 的操作。您會(huì)發(fā)現(xiàn) API 和 dict 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'

獲取所有獲取到的值

您可以使用 dict API 來獲取所有的值:

>>> product.keys()
['price', 'name']

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

其他任務(wù)

復(fù)制 item:

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

>>> product3 = product2.copy()
>>> print product3
Product(name='Desktop PC', price=1000)

根據(jù) item 創(chuàng)建字典(dict)

>>> dict(product) # create a dict from all populated values
{'price': 1000, 'name': 'Desktop PC'}

根據(jù)字典(dict)創(chuàng)建 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'

擴(kuò)展 Item

您可以通過繼承原始的 Item 來擴(kuò)展 item(添加更多的字段或者修改某些字段的元數(shù)據(jù))。

例如:

class DiscountedProduct(Product):
    discount_percent = scrapy.Field(serializer=str)
    discount_expiration_date = scrapy.Field()

您也可以通過使用原字段的元數(shù)據(jù),添加新的值或修改原來的值來擴(kuò)展字段的元數(shù)據(jù):

class SpecificProduct(Product):
    name = scrapy.Field(Product.fields['name'], serializer=my_serializer)

這段代碼在保留所有原來的元數(shù)據(jù)值的情況下添加(或者覆蓋)了 name 字段的 serializer。

Item 對象

class scrapy.item.Item([arg])

返回一個(gè)根據(jù)給定的參數(shù)可選初始化的 item。

Item復(fù)制了標(biāo)準(zhǔn)的 dict API。包括初始化函數(shù)也相同。Item 唯一額外添加的屬性是:

fields

一個(gè)包含了 item 所有聲明的字段的字典,而不僅僅是獲取到的字段。該字典的 key 是字段(field)的名字,值是 Item 聲明中使用到的 Field 對象。

字段(Field)對象

class scrapy.item.Field([arg])

Field 僅僅是內(nèi)置的 dict 類的一個(gè)別名,并沒有提供額外的方法或者屬性。換句話說,F(xiàn)ield 對象完完全全就是 Python 字典(dict)。被用來基于類屬性(class attribute)的方法來支持 item 聲明語法。

上一篇:Spider 中間件(Middleware)下一篇:例子