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ī)則。
要使用 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 位置提取:
//div[@class="product_name"]
//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。
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ā)生了這些事情:
需要注意的是,輸入和輸出處理器都是可調(diào)用對象,調(diào)用時傳入需要被分析的數(shù)據(jù), 處理后返回分析得到的值。因此你可以使用任意函數(shù)作為輸入、輸出處理器。唯一需注意的是它們必須接收一個(并且只是一個)迭代器性質(zhì)的 positional 參數(shù)。