如何创建自定义废料项目导出器?

2024-05-28 18:10:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个基于JsonLinesItemExporter的自定义废弃项导出器,这样我就可以稍微改变它生成的结构。在

我已经阅读了这里的文档http://doc.scrapy.org/en/latest/topics/exporters.html,但它没有说明如何创建自定义导出器、将其存储在何处或如何将其链接到管道。在

我已经确定了如何与饲料出口商进行定制,但这不符合我的要求,因为我想从我的管道给这个出口商打电话。在

下面是我想出的代码,它存储在名为^{的项目根目录下的一个文件中


from scrapy.contrib.exporter import JsonLinesItemExporter

class FanItemExporter(JsonLinesItemExporter):

    def __init__(self, file, **kwargs):
        self._configure(kwargs, dont_fail=True)
        self.file = file
        self.encoder = ScrapyJSONEncoder(**kwargs)
        self.first_item = True

    def start_exporting(self):
        self.file.write("""{
            'product': [""")

    def finish_exporting(self):
        self.file.write("]}")

    def export_item(self, item):
        if self.first_item:
            self.first_item = False
        else:
            self.file.write(',\n')
        itemdict = dict(self._get_serialized_fields(item))
        self.file.write(self.encoder.encode(itemdict))

我只是试着用FanItemExporter从我的管道中调用它,并尝试导入的变体,但没有产生任何结果。在


Tags: selftrueencoder管道defitemkwargsfile
1条回答
网友
1楼 · 发布于 2024-05-28 18:10:30

诚然,这些零碎的文件并没有明确说明出口商品的地点。要使用项目导出器,请执行以下步骤。在

  1. 选择项导出器类并将其导入到项目目录中的pipeline.py。它可以是预定义的项导出器(例如XmlItemExporter)或用户定义的(如问题中定义的FanItemExporter
  2. pipeline.py中创建项管道类。在此类中实例化导入的项导出器。细节将在后面的答案中解释。在
  3. 现在,在settings.py文件中注册这个管道类。在

以下是每个步骤的详细说明。问题的解决方案包含在每个步骤中。在

步骤1

  • 如果使用预定义的项导出器类,请从scrapy.exporters模块导入它。
    前任: from scrapy.exporters import XmlItemExporter

  • 如果需要自定义导出器,请在文件中定义自定义类。我建议将类放在exporters.py文件中。将此文件放在项目文件夹中(其中settings.pyitems.py所在的位置)。在

    在创建新的子类时,导入BaseItemExporter总是一个好主意。如果我们打算完全改变功能,那就比较合适了。但是,在这个问题中,大多数功能都接近JsonLinesItemExporter

因此,我附加了同一个ItemExporter的两个版本。一个版本扩展了BaseItemExporter类,另一个扩展了JsonLinesItemExporter

版本1:扩展BaseItemExporter

由于BaseItemExporter是父类,start_exporting()finish_exporting()export_item()必须重写以满足我们的需要。在

from scrapy.exporters import BaseItemExporter
from scrapy.utils.serialize import ScrapyJSONEncoder
from scrapy.utils.python import to_bytes

class FanItemExporter(BaseItemExporter):

    def __init__(self, file, **kwargs):
        self._configure(kwargs, dont_fail=True)
        self.file = file
        self.encoder = ScrapyJSONEncoder(**kwargs)
        self.first_item = True

    def start_exporting(self):
        self.file.write(b'{\'product\': [')

    def finish_exporting(self):
        self.file.write(b'\n]}')

    def export_item(self, item):
        if self.first_item:
            self.first_item = False
        else:
            self.file.write(b',\n')
        itemdict = dict(self._get_serialized_fields(item))
        self.file.write(to_bytes(self.encoder.encode(itemdict)))

版本2:扩展JsonLinesItemExporter

JsonLinesItemExporter提供了与export_item()方法完全相同的实现。因此只有start_exporting()finish_exporting()方法被重写。在

JsonLinesItemExporter的实现可以在python_dir\pkgs\scrapy-1.1.0-py35_0\Lib\site-packages\scrapy\exporters.py文件夹中看到

^{pr2}$

注意:将数据写入文件时,请务必注意,标准项导出器类需要二进制文件。因此,文件必须以二进制模式打开(b)。出于同样的原因,两个版本中的write()方法都将bytes写入文件。在

步骤2

正在创建项管道类。在

from project_name.exporters import FanItemExporter

class FanExportPipeline(object):
    def __init__(self, file_name):
        # Storing output filename
        self.file_name = file_name
        # Creating a file handle and setting it to None
        self.file_handle = None

    @classmethod
    def from_crawler(cls, crawler):
        # getting the value of FILE_NAME field from settings.py
        output_file_name = crawler.settings.get('FILE_NAME')

        # cls() calls FanExportPipeline's constructor
        # Returning a FanExportPipeline object
        return cls(output_file_name)

    def open_spider(self, spider):
        print('Custom export opened')

        # Opening file in binary-write mode
        file = open(self.file_name, 'wb')
        self.file_handle = file

        # Creating a FanItemExporter object and initiating export
        self.exporter = FanItemExporter(file)
        self.exporter.start_exporting()

    def close_spider(self, spider):
        print('Custom Exporter closed')

        # Ending the export to file from FanItemExport object
        self.exporter.finish_exporting()

        # Closing the opened output file
        self.file_handle.close()

    def process_item(self, item, spider):
        # passing the item to FanItemExporter object for expoting to file
        self.exporter.export_item(item)
        return item

步骤3

由于定义了项导出管道,请在settings.py文件中注册此管道。还要将字段FILE_NAME添加到settings.py文件中。此字段包含输出文件的文件名。在

将以下行添加到settings.py文件中。在

FILE_NAME = 'path/outputfile.ext'
ITEM_PIPELINES = {
    'project_name.pipelines.FanExportPipeline' : 600,
}

如果ITEM_PIPELINES已经取消注释,那么将以下行添加到ITEM_PIPELINES字典中。在

'project_name.pipelines.FanExportPipeline' : 600,

这是创建自定义项导出管道的一种方法。在

相关问题 更多 >

    热门问题