Item Loaders 提供了一種便捷的方式填充抓取到的:Items
。雖然 Items 可以使用自帶的類(lèi)字典形式 API 填充,但是 Items Loaders 提供了更便捷的 API,可以分析原始數(shù)據(jù)并對(duì) Item 進(jìn)行賦值。
從另一方面來(lái)說(shuō),Items 提供保存抓取數(shù)據(jù)的容器,而 Item Loaders 提供的是 填充 容器的機(jī)制。
Item Loaders 提供的是一種靈活,高效的機(jī)制,可以更方便的被 spider 或 source format (HTML,XML,etc)擴(kuò)展,并 override 更易于維護(hù)的、不同的內(nèi)容分析規(guī)則。
要使用 Item Loader, 你必須先將它實(shí)例化。你可以使用類(lèi)似字典的對(duì)象(例如: Item or dict)來(lái)進(jìn)行實(shí)例化,或者不使用對(duì)象也可以,當(dāng)不用對(duì)象進(jìn)行實(shí)例化的時(shí)候,Item 會(huì)自動(dòng)使用 ItemLoader.default\_item_class
屬性中指定的 Item 類(lèi)在 Item Loader constructor 中實(shí)例化。
然后,你開(kāi)始收集數(shù)值到 Item Loader 時(shí),通常使用 Selectors。你可以在同一個(gè) item field 里面添加多個(gè)數(shù)值;Item Loader 將知道如何用合適的處理函數(shù)來(lái)“添加”這些數(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 字段被從頁(yè)面中兩個(gè)不同的 XPath 位置提取:
//div[@class="product_name"]
//div[@class="product_title"]
換言之,數(shù)據(jù)通過(guò)用 add_xpath()
的方法,把從兩個(gè)不同的 XPath 位置提取的數(shù)據(jù)收集起來(lái). 這是將在以后分配給 name
字段中的數(shù)據(jù)?
之后,類(lèi)似的請(qǐng)求被用于 price 和 stock 字段 (后者使用 CSS selector 和 add_css()
方法), 最后使用不同的方法 add_value()
對(duì) last_update
填充文本值(today
)。
最終,當(dāng)所有數(shù)據(jù)被收集起來(lái)之后, 調(diào)用 ItemLoader.load_item() 方法,實(shí)際上填充并且返回了之前通過(guò)調(diào)用 add_xpath(),add_css(),and add_value()所提取和收集到的數(shù)據(jù)的 Item。
Item Loader 在每個(gè)(Item)字段中都包含了一個(gè)輸入處理器和一個(gè)輸出處理器? 輸入處理器收到數(shù)據(jù)時(shí)立刻提取數(shù)據(jù) (通過(guò) add_xpath(),add_css()或者 add_value()方法)之后輸入處理器的結(jié)果被收集起來(lái)并且保存在 ItemLoader 內(nèi). 收集到所有的數(shù)據(jù)后, 調(diào)用 ItemLoader.load_item()方法來(lái)填充,并得到填充后的 Item 對(duì)象。這是當(dāng)輸出處理器被和之前收集到的數(shù)據(jù)(和用輸入處理器處理的)被調(diào)用.輸出處理器的結(jié)果是被分配到 Item 的最終值?
讓我們看一個(gè)例子來(lái)說(shuō)明如何輸入和輸出處理器被一個(gè)特定的字段調(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)用對(duì)象,調(diào)用時(shí)傳入需要被分析的數(shù)據(jù), 處理后返回分析得到的值。因此你可以使用任意函數(shù)作為輸入、輸出處理器。唯一需注意的是它們必須接收一個(gè)(并且只是一個(gè))迭代器性質(zhì)的 positional 參數(shù)。