2016-08-24 68 views
7

我是scrapy的新手,我知道項目用於填充刮取的數據,但我無法理解項目和項目加載器之間的差異。我試圖閱讀一些示例代碼,他們使用項目加載器來存儲而不是項目,我不明白爲什麼。 Scrapy文檔對我來說還不夠清楚。任何人都可以給出一個簡單的解釋(更好的例子)關於什麼時候使用物品裝載機以及它們提供什麼額外的設施來提供物品?scrapy中的項目vs項目加載器

回答

8

我真的很喜歡在文檔官方的解釋:

項目裝載機用於填充提供一個方便的機制刮 項目。儘管可以使用自己的 類似字典的API來填充項目,但項目加載器通過自動執行一些常見的任務(如在分配原始提取數據之前解析原始提取的數據),提供了更方便的API ,以便從刮取過程填充它們。

換句話說,Items提供了刮取數據的容器,而 Item Loaders提供了填充該容器的機制。

最後一段應該回答你的問題。
項目裝載機是偉大的,因爲它們允許你有這麼多的處理快捷方式,並重用一堆代碼保持一切整潔,乾淨,易於理解。

比較示例。比方說,我們要湊這個項目:

class MyItem(Item): 
    full_name = Field() 
    bio = Field() 
    age = Field() 
    weight = Field() 
    height = Field() 

項目唯一的方法會是這個樣子:

def parse(self, response): 
    full_name = response.xpath("//div[contains(@class,'name')]/text()").extract() 
    # i.e. returns ugly ['John\n', '\n\t ', ' Snow'] 
    item['full_name'] = ' '.join(i.strip() for i in full_name if i.strip()) 
    bio = response.xpath("//div[contains(@class,'bio')]/text()").extract() 
    item['bio'] = ' '.join(i.strip() for i in full_name if i.strip()) 
    age = response.xpath("//div[@class='age']/text()").extract_first(0) 
    item['age'] = int(age) 
    weight = response.xpath("//div[@class='weight']/text()").extract_first(0) 
    item['weight'] = int(age) 
    height = response.xpath("//div[@class='height']/text()").extract_first(0) 
    item['height'] = int(age) 
    return item 

VS項目裝載機做法:

# define once in items.py 
from scrapy.loader.processors import Compose, MapCompose, Join, TakeFirst 
clean_text = Compose(MapCompose(lambda v: v.strip()), Join()) 
to_int = Compose(TakeFirst(), int) 

class MyItemLoader(ItemLoader): 
    default_item_class = MyItem 
    full_name_out = clean_text 
    bio_out = clean_text 
    age_out = to_int 
    weight_out = to_int 
    height_out = to_int 

# parse as many different places and times as you want 
def parse(self, response): 
    loader = MyItemLoader(selector=response) 
    loader.add_xpath('full_name', "//div[contains(@class,'name')]/text()") 
    loader.add_xpath('bio', "//div[contains(@class,'bio')]/text()") 
    loader.add_xpath('age', "//div[@class='age']/text()") 
    loader.add_xpath('weight', "//div[@class='weight']/text()") 
    loader.add_xpath('height', "//div[@class='height']/text()") 
    return loader.load_item() 

正如你所看到的項目裝載機非常乾淨並且更容易擴展。假設你有20個以上的領域有很多共享相同的處理邏輯,如果沒有Item Loader就會自殺。 項目裝載機很棒,你應該使用它們!

+1

該項目示例創建了很多不必要的變量,這使得它看起來更加混亂,'item [「bio」] = response.xpath(「// div [contains(@ class,'bio')]/text ()「)。extract()' –

+0

很酷的東西。謝謝 ! – Airbear

+0

@PadraicCunningham我沒有看到任何不必要的變量,因爲'bio'字段必須被分條和加入。你的例子只是把清單中的值清單。 – Granitosaurus