2015-04-29 13 views
9

machte ich die Verbesserung gemäß dem Vorschlag von alexce unten. Was ich brauche, ist wie das Bild unten. Jede Zeile/Zeile sollte jedoch eine Überprüfung sein: mit Datum, Bewertung, Bewertungstext und Link.Scrapy Pipeline zu exportieren CSV-Datei im richtigen Format

Ich brauche Punkt Prozessor Prozess jede Überprüfung von jeder Seite zu lassen.
Derzeit TakeFirst() nimmt nur die erste Bewertung der Seite. Also 10 Seiten, ich habe nur 10 Zeilen/Zeilen wie im Bild unten.

enter image description here

Spinne Code ist unten:

import scrapy 
from amazon.items import AmazonItem 

class AmazonSpider(scrapy.Spider): 
    name = "amazon" 
    allowed_domains = ['amazon.co.uk'] 
    start_urls = [ 
    'http://www.amazon.co.uk/product-reviews/B0042EU3A2/'.format(page) for  page in xrange(1,114) 

] 

def parse(self, response): 
    for sel in response.xpath('//*[@id="productReviews"]//tr/td[1]'): 
     item = AmazonItem() 
     item['rating'] = sel.xpath('div/div[2]/span[1]/span/@title').extract() 
     item['date'] = sel.xpath('div/div[2]/span[2]/nobr/text()').extract() 
     item['review'] = sel.xpath('div/div[6]/text()').extract() 
     item['link'] = sel.xpath('div/div[7]/div[2]/div/div[1]/span[3]/a/@href').extract() 

     yield item 
+0

Sie wollen nur die Überprüfung Text in der Ausgabe zu sein, nicht wahr? – alecxe

+0

@alecxe nein, mein Herr. nur als ein Beispiel. Ich möchte Bewertung, Datum, Bewertung, Link als 4 verschiedene Spalten in Excel haben. Vielen Dank! –

+0

@alecxe das ist mein Versuch unten. Es hat nicht funktioniert. wahrscheinlich, weil ich die Mechanik für die Pipeline nicht verstehe. import CSV Klasse CsvWriterPipeline (object): def __init __ (self): self.csvwriter = csv.writer (open ('amazon.csv', 'wb')) def process_item (self, Element, Spinne): self.csvwriter.writtenow (Artikel ['Bewertung'], Artikel ['Datum'], Artikel ['Bericht'], Artikel ['Link']) Artikel zurückgeben –

Antwort

16

ich von Grund auf neu gestartet und die folgende Spinne sollte mit

scrapy crawl amazon -t csv -o Amazon.csv --loglevel=INFO

so ausgeführt werden, dass die CSV-Datei mit einem Tabellenkalkulations Öffnen zeigt für mich

enter image description here

hoffe, das hilft :-)

import scrapy 

class AmazonItem(scrapy.Item): 
    rating = scrapy.Field() 
    date = scrapy.Field() 
    review = scrapy.Field() 
    link = scrapy.Field() 

class AmazonSpider(scrapy.Spider): 

    name = "amazon" 
    allowed_domains = ['amazon.co.uk'] 
    start_urls = ['http://www.amazon.co.uk/product-reviews/B0042EU3A2/' ] 

    def parse(self, response): 

     for sel in response.xpath('//table[@id="productReviews"]//tr/td/div'): 

      item = AmazonItem() 
      item['rating'] = sel.xpath('./div/span/span/span/text()').extract() 
      item['date'] = sel.xpath('./div/span/nobr/text()').extract() 
      item['review'] = sel.xpath('./div[@class="reviewText"]/text()').extract() 
      item['link'] = sel.xpath('.//a[contains(.,"Permalink")]/@href').extract() 
      yield item 

     xpath_Next_Page = './/table[@id="productReviews"]/following::*//span[@class="paging"]/a[contains(.,"Next")]/@href' 
     if response.xpath(xpath_Next_Page): 
      url_Next_Page = response.xpath(xpath_Next_Page).extract()[0] 
      request = scrapy.Request(url_Next_Page, callback=self.parse) 
      yield request 
+0

Sie sind großartig !!! Danke! Es funktionierte wie ein Zauber. gelegentlich würde ich hier und da einen Link/URL verpassen. Aber es ist nichts wichtiges, ich kann meinen nächsten Schritt für die Postdatenverarbeitung jetzt fortsetzen! –

12

Wenn -t csv mit (wie von Frank in Kommentaren vorgeschlagen) aus irgendeinem Grund nicht für Sie arbeiten, können Sie immer direkt eingebaute in CsvItemExporter verwenden in the custom pipeline, zB:

from scrapy import signals 
from scrapy.contrib.exporter import CsvItemExporter 


class AmazonPipeline(object): 
    @classmethod 
    def from_crawler(cls, crawler): 
     pipeline = cls() 
     crawler.signals.connect(pipeline.spider_opened, signals.spider_opened) 
     crawler.signals.connect(pipeline.spider_closed, signals.spider_closed) 
     return pipeline 

    def spider_opened(self, spider): 
     self.file = open('output.csv', 'w+b') 
     self.exporter = CsvItemExporter(self.file) 
     self.exporter.start_exporting() 

    def spider_closed(self, spider): 
     self.exporter.finish_exporting() 
     self.file.close() 

    def process_item(self, item, spider): 
     self.exporter.export_item(item) 
     return item 

, die Sie ITEM_PIPELINES hinzufügen müssen:

ITEM_PIPELINES = { 
    'amazon.pipelines.AmazonPipeline': 300 
} 

Außerdem würde ich ein Item Loader mit Eingabe- und Ausgabe-Prozessoren verwenden, um die Überprüfung Text zu verbinden und neue Linien mit Leerzeichen ersetzen. Erstellen Sie eine ItemLoader Klasse:

from scrapy.contrib.loader import ItemLoader 
from scrapy.contrib.loader.processor import TakeFirst, Join, MapCompose 


class AmazonItemLoader(ItemLoader): 
    default_output_processor = TakeFirst() 

    review_in = MapCompose(lambda x: x.replace("\n", " ")) 
    review_out = Join() 

Dann verwenden Sie es zu konstruieren ein Item:

def parse(self, response): 
    for sel in response.xpath('//*[@id="productReviews"]//tr/td[1]'): 
     loader = AmazonItemLoader(item=AmazonItem(), selector=sel) 

     loader.add_xpath('rating', './/div/div[2]/span[1]/span/@title') 
     loader.add_xpath('date', './/div/div[2]/span[2]/nobr/text()') 
     loader.add_xpath('review', './/div/div[6]/text()') 
     loader.add_xpath('link', './/div/div[7]/div[2]/div/div[1]/span[3]/a/@href') 

     yield loader.load_item() 
+0

Vielen Dank, dass Sie mir die Richtung gezeigt haben! Ich denke, Loader ist der richtige Weg. Ich muss etwas Feinabstimmung vornehmen, um das richtige Layout für meine Bedürfnisse zu finden. Ich kann immer noch zu dir zurückkommen, wenn ich feststecke. ;-) –

+0

Ich stecke wieder fest. Ich habe die ursprüngliche Frage bearbeitet, um die Verbesserung basierend auf Ihrem Vorschlag zu reflektieren. kann es immer noch nicht so lösen, wie ich es gerne hätte. Könnten Sie die Frage oben noch einmal überprüfen? –

Verwandte Themen