2016-08-24 2 views
7

Ich bin ziemlich neu zu scrapy, ich weiß, dass Elemente verwendet werden, um Scraped Daten zu füllen, aber ich kann nicht den Unterschied zwischen Artikel und Artikel Lader verstehen. Ich habe versucht, einige Beispielcodes zu lesen, sie haben Artikellader anstelle von Artikeln verwendet und ich kann nicht verstehen warum. Scrapy Dokumentation war nicht klar genug für mich. Kann jemand eine einfache Erklärung geben (besser mit Beispiel), wenn Artikellader verwendet werden und welche zusätzlichen Einrichtungen sie über Gegenstände bieten?Items vs Artikel Loader in scrapy

Antwort

8

Ich mag die offizielle Erklärung in der Dokumentation:

Artikel Lader bietet einen bequemen Mechanismus Artikel geschabt zum Bestücken. Obwohl Elemente mit ihrer eigenen wörterbuchähnlichen API gefüllt werden können, bieten Objektlader eine viel bequemere API für das Ausfüllen von einem Scraping-Prozess, indem einige allgemeine Aufgaben wie das Parsen der unverarbeiteten extrahierten Daten vor dem Zuweisen automatisiert werden.

Mit anderen Worten, Elemente bieten den Container von Scraped-Daten, während Element Loader den Mechanismus zum Füllen dieses Containers bereitstellen.

Letzter Absatz sollte Ihre Frage beantworten.
Artikellader sind großartig, da sie Ihnen erlauben, so viele Verarbeitungsabkürzungen zu haben und eine Menge Code wiederzuverwenden, um alles sauber, sauber und verständlich zu halten.

Vergleich Beispiel Fall. Lets sagen, dass wir diesen Artikel kratzen wollen:

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 Artikel-Lader nähern:

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

Wenn Sie den Artikel sehen

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

Artikel nur Ansatz wie folgt aussehen würde Lader ist so viel sauberer und einfacher zu skalieren. Nehmen wir an, Sie haben 20 weitere Felder, von denen viele die gleiche Verarbeitungslogik haben, wäre ein Selbstmord ohne Item Loader. Artikel Loader sind super und du solltest sie benutzen!

+1

Das Item Beispiel erzeugt eine Menge unnötiger Variablen, die es viel unübersichtlicher aussehen lassen, 'item [" bio "] = response.xpath (" // div [enthält (@ class, 'bio')]/text() "). extrahieren()' –

+0

Coole Sachen. Vielen Dank ! – Airbear

+0

@PadraicCunningham Ich sehe hier keine unnötigen Variablen, da das 'bio'-Feld gestreift und verknüpft werden muss. Ihr Beispiel würde nur eine Liste von Werten ohne Aufräumen setzen. – Granitosaurus