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

Item Loaders

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ī)則。

Using Item Loaders to populate items

要使用 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 位置提取:

  1. //div[@class="product_name"]
  2. //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。

Input and Output processors

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ā)生了這些事情:

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

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