导出CSV的多个蜘蛛/ Scrapy /管道缺少数据

时间:2018-11-09 10:16:44

标签: python scrapy

我根据此处的一些示例实现了管道。我正在尝试在单个CSV文件中导出多个蜘蛛(由单个文件而不是在命令行中启动)的所有信息。

但是,似乎显示在外壳中的某些数据(大约10%)没有记录到CSV中。这是因为蜘蛛正在同时写作吗?

如何解决此问题,使其在脚本中收集单个CSV中的所有数据?我正在使用CrawlerProcess来发射蜘蛛。

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


class ScrapybotPipeline(object):

def __init__(self):
    self.files = {}

@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):
    file = open('result_extract.csv', 'w+b')
    self.files[spider] = file
    self.exporter = CsvItemExporter(file)
    self.exporter.fields_to_export = ['ean', 'price', 'desc', 'company']
    self.exporter.start_exporting()

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

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

1 个答案:

答案 0 :(得分:1)

根据您的描述,我知道您正在处理多个蜘蛛。只是为了确认:您是否同时处理? (在相同的抓取过程内)?

根据您共享的代码。您正在尝试为每个蜘蛛维护一个输出文件对象,但写入所有相同的路径。在spider_opened中:

file = open('result_extract.csv', 'w+b')
self.files[spider] = file

这被认为是问题的根本原因。

由于只有一个文件(如文件系统上)要写入,因此可以只打开一次即可。修改后的代码:

class ScrapybotPipeline(object):

    def __init__(self):
        self.file = None

    @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('result_extract.csv', 'w+b')
        self.exporter = CsvItemExporter(self.file)
        self.exporter.fields_to_export = ['ean', 'price', 'desc', 'company']
        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