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

Item Loaders

Item Loaders 提供了一種便捷的方式填充抓取到的:Items。雖然 Items 可以使用自帶的類字典形式 API 填充,但是 Items Loaders 提供了更便捷的 API,可以分析原始數(shù)據(jù)并對 Item 進行賦值。

從另一方面來說,Items 提供保存抓取數(shù)據(jù)的容器,而 Item Loaders 提供的是 填充 容器的機制。

Item Loaders 提供的是一種靈活,高效的機制,可以更方便的被 spider 或 source format (HTML,XML,etc)擴展,并 override 更易于維護的、不同的內(nèi)容分析規(guī)則。

Using Item Loaders to populate items

要使用 Item Loader, 你必須先將它實例化。你可以使用類似字典的對象(例如: Item or dict)來進行實例化,或者不使用對象也可以,當不用對象進行實例化的時候,Item 會自動使用 ItemLoader.default\_item_class 屬性中指定的 Item 類在 Item Loader constructor 中實例化。

然后,你開始收集數(shù)值到 Item Loader 時,通常使用 Selectors。你可以在同一個 item field 里面添加多個數(shù)值;Item Loader 將知道如何用合適的處理函數(shù)來“添加”這些數(shù)值。

下面是在 Spider 中典型的 Item Loader 的用法,使用 Items chapter聲明的 Product item:

from scrapy.contrib.loader import ItemLoader
from myproject.items import Product

def 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()

快速查看這些代碼之后,我們可以看到發(fā)現(xiàn) name 字段被從頁面中兩個不同的 XPath 位置提取:

  1. //div[@class="product_name"]
  2. //div[@class="product_title"]

換言之,數(shù)據(jù)通過用 add_xpath()的方法,把從兩個不同的 XPath 位置提取的數(shù)據(jù)收集起來. 這是將在以后分配給 name 字段中的數(shù)據(jù)?

之后,類似的請求被用于 price 和 stock 字段 (后者使用 CSS selector 和 add_css() 方法), 最后使用不同的方法 add_value()last_update 填充文本值(today)。

最終,當所有數(shù)據(jù)被收集起來之后, 調(diào)用 ItemLoader.load_item() 方法,實際上填充并且返回了之前通過調(diào)用 add_xpath(),add_css(),and add_value()所提取和收集到的數(shù)據(jù)的 Item。

Input and Output processors

Item Loader 在每個(Item)字段中都包含了一個輸入處理器和一個輸出處理器? 輸入處理器收到數(shù)據(jù)時立刻提取數(shù)據(jù) (通過 add_xpath(),add_css()或者 add_value()方法)之后輸入處理器的結果被收集起來并且保存在 ItemLoader 內(nèi). 收集到所有的數(shù)據(jù)后, 調(diào)用 ItemLoader.load_item()方法來填充,并得到填充后的 Item 對象。這是當輸出處理器被和之前收集到的數(shù)據(jù)(和用輸入處理器處理的)被調(diào)用.輸出處理器的結果是被分配到 Item 的最終值?

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

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)

發(fā)生了這些事情:

  1. 從 xpath1 提取出的數(shù)據(jù),傳遞給 輸入處理器 的 name 字段。輸入處理器的結果被收集和保存在 Item Loader 中(但尚未分配給該 Item)?
  2. 從 xpath2 提取出來的數(shù)據(jù),傳遞給(1)中使用的相同的 輸入處理器。輸入處理器的結果被附加到在(1)中收集的數(shù)據(jù)(如果有的話)?
  3. 和之前相似,只不過這里的數(shù)據(jù)是通過 css CSS selector 抽取,之后傳輸?shù)皆?1)和(2)使用 的 input processor 中。最終輸入處理器的結果被附加到在(1)和(2)中收集的數(shù)據(jù)之后 (如果存在數(shù)據(jù)的話)。
  4. 這里的處理方式也和之前相似,但是此處的值是通過 add_value 直接賦予的, 而不是利用 XPath 表達式或 CSS selector 獲取。得到的值仍然是被傳送到輸入處理器。 在這里例程中,因為得到的值并非可迭代,所以在傳輸?shù)捷斎胩幚砥髦靶枰獙⑵?轉化為可迭代的單個元素,這才是它所接受的形式。
  5. 在之前步驟中所收集到的數(shù)據(jù)被傳送到 output processor 的 name field 中。輸出處理器的結果就是賦到 item 中 name field 的值。

需要注意的是,輸入和輸出處理器都是可調(diào)用對象,調(diào)用時傳入需要被分析的數(shù)據(jù), 處理后返回分析得到的值。因此你可以使用任意函數(shù)作為輸入、輸出處理器。唯一需注意的是它們必須接收一個(并且只是一個)迭代器性質(zhì)的 positional 參數(shù)。

上一篇:Web Service下一篇:常見問題(FAQ)