2017-11-04 6 views
-1

Kann mir bitte jemand das erklären?
In meiner Spinne habe ich Code zum Extrahieren von Daten mit XPath.Warum in Scrapy scrapped Text ist als String in Spider, aber als Liste in der Pipeline?

price_euro = add.xpath('.//strong[@class="price price--eur"]/text()').extract_first() 
print 'price_euro', price_euro, type(price_euro) 

und was ich bekommen ist:

price_euro 25.500 <type 'unicode'> 

und ich verstehe das, ich habe es als String (Unicode), weil ich verwendet habe .extract_first() und das ist, was ich will.

Aber in meiner Pipeline,

print "item['price_euro']", item['price_euro'], type(item['price_euro']) 

Ich habe es als eine Liste

item['price_euro'] [u'25.500 '] <type 'list'> 

für mich nicht das große Problem Dies ist, aber es ist ärgerlich, weil jedes Mal, wenn ich zugreifen möchten Ich muss am Ende [0] hinzufügen. z.B. item ['price_euro'] [0]

Kann ich das deaktivieren und sollte ich?
Was ist die Logik dahinter?

Danke

Wie ich price_euro

l = ItemLoader(item=MyItem(), response=response) 
l.add_value('price_euro', price_euro)  
yield l.load_item() 
+0

wo weisen Sie dem Artikel den Preis zu? Wie sieht der gesamte Artikel aus, wenn er gedruckt wird? –

+0

@omu_negru Ich habe einen Code zur Frage hinzugefügt. – WebOrCode

Antwort

2

Die ItemLoader ermöglicht Aufruf add_value() (sowie add_css() und add_xpath()) mehrere Male für das gleiche Feld hinzuzufügen. Dies ist hilfreich, wenn die gesuchten Informationen an mehreren Stellen der HTML-Quelle gefunden werden können oder wenn das HTML-Layout zwischen den Anforderungen abweicht. Um dies zu berücksichtigen, speichert der Objektlader alle Feldwerte in Listen.

Wenn Sie genau einen Wert für das Feld erwarten (wie für Ihre Preisinformationen), können Sie dem Elementlader mitteilen, wie die Liste konvertiert wird, wenn load_item() aufgerufen wird, indem Sie output processor angeben. Die kanonische Weg, dies zu tun ist durch die Subklassen der ItemLoader Klasse:

from scrapy.loader import ItemLoader 
from scrapy.loader.processors import TakeFirst 

class MyItemLoader(ItemLoader): 
    default_item_class = MyItem 
    price_euro_out = TakeFirst() 

Sie dann diesen Artikel Lader vor als bevölkern können, mit dem zusätzlichen Kopf, dass Sie nicht mehr das Element loader sagen müssen, welches Element Typ Verwendung:

l = MyItemLoader(response=response) 
l.add_value('price_euro', price_euro)  
yield l.load_item() 

Für das Beispiel Code, den Sie geschrieben, können Sie sogar Ihre manuelle Extraktion über die add_xpath() Verfahren vermeiden und Weitergabe add als selector Stichwort Argument für den Artikel Lader:

l = MyItemLoader(selector=add) 
l.add_xpath('price_euro', './/strong[@class="price price--eur"]/text()')  
yield l.load_item() 

Wenn Sie diese aktivieren mögen „das erste Listenelement“ Verhalten für alle Felder Ihres Artikels, können Sie auch einen Standard-Ausgabe-Prozessor für Ihren Artikel loader erklären können:

class MyItemLoader(ItemLoader): 
    default_item_class = MyItem 
    default_output_processor = TakeFirst() 

Die Scrapy Docs haben eine list of built-in processors.

+0

danke für deine antwort, jetzt denkt sinnvoll. Um dieses Problem zu lösen, habe ich eine Pipeline erstellt, um das einzige Erste zu bekommen. Ich benutze Scrapy letzte Woche, es ist ein sehr guter Rahmen, sobald Sie die Logik dahinter verstehen. Ich werde versuchen, diesen Ansatz zu verwenden. – WebOrCode

Verwandte Themen