【问题标题】:Scrapy Item Pipelines and file namingScrapy Item Pipelines 和文件命名
【发布时间】:2020-06-16 05:04:29
【问题描述】:

我正在尝试使用蜘蛛名称和日期命名管道输出文件。 我编写了一小段代码来调用文件的日期。 问题在于蜘蛛名称。 下面介绍两种方法。两者都有效,但我想了解其中的细微差别。 第一种方法从 PyCharm 生成一个我不理解的建议,特别是因为它遵循 scrapy docs 的示例。

第一种方法:

# pipelines.py

# Cannot add spider as input to class Pipeline
class CsvPipeline(object):

    def open_spider(self, spider):
        # Call to put file in correct directory
        redefine_dir(spider, file_type='csv')
        # Call to name file correctly
        name = dated_filename(spider, '.csv')
        # PyCharm insists the following two lines should be in __init__; Why?
        # Only seem to be able to have spider as input to open_spider and not the class
        self.file = open(name, 'wb')
        self.exporter = CsvItemExporter(self.file)
        self.exporter.start_exporting()

    def close_spider(self):
        self.exporter.finish_exporting()
        self.file.close()

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

第二种方法:

class JsonPipeline(object):
    def __init__(self):
        # As I cannot figure out how spider is an input to __init__ I have to create a temporary file
        # This temporary file is renamed later.
        print('Current working directory:', os.getcwd())
        if os.getcwd() == 'C:\\PycharmProjects\\ABC\\abc\\run':
            os.chdir('..')
        elif os.getcwd() == 'C:\\PycharmProjects\\ABC':
            os.chdir('abc')
        print('Current working directory now:', os.getcwd())
        # Temporary file created
        self.file = open('data/raw.json', 'wb')
        self.exporter = JsonItemExporter(self.file)
        self.exporter.start_exporting()

    def close_spider(self, spider):
        self.exporter.finish_exporting()
        self.file.close()
        new_name = dated_filename(spider, '.json')
        print('Current working directory:', os.getcwd())
        if os.getcwd() == 'C:\\PycharmProjects\\ABC\\abc\\run':
            os.chdir('..')
        elif os.getcwd() == 'C:\\PycharmProjects\\ABC':
            os.chdir('abc')
        print('Current working directory now:', os.getcwd())
        # Rename file to dated filename
        rename('data/raw.json', new_name)

    def process_item(self, item):
        self.exporter.export_item(item)
        return item
  1. 是否可以包含蜘蛛作为 Pipeline 类的输入?如果有,怎么做?
  2. 是否可以包含蜘蛛作为管道类 init 的输入?如果有,怎么做?
  3. 为什么 PyCharm 坚持我应该将 self.file 和 self.exporter 放在 init 下?
  4. 有更好的想法吗?

【问题讨论】:

  • 第一种方法有什么问题,除了 PyCharm 警告?您可以通过使用None 将这些变量定义为__init__ 中的值来使它们静音。
  • 我发现这些方法中的一种或两种会导致关闭蜘蛛的问题。需要进一步挖掘以了解原因。我理解为什么 PyCharm 想要在 init 中使用这些:最初而不是稍后配置类参数。如果我使用None 文件参数未定义为_io.FileIO 并创建一个异常错误,因为它不能被爬虫/管道写入。

标签: python scrapy


【解决方案1】:

我发现了这个: Share global variables across modules

所以我创建了一个 config.py:

#config.py
name = None

在我的蜘蛛中:

#spiderx.py

import abc.config

class SpiderBotX(Spider):
    name = 'spiderx'
    abc.config.name = name
    ...

然后修改如下:

#pipelines.py
import abc.config

class JsonPipeline:
    def __init__(self):
        # use config.py name variable to store and pass spider name between modules
        prefix = abc.config.name
        redefine_dir(prefix, file_type='csv')
        filename = dated_filename(prefix, '.csv')
        # open defines as _io.FileIO
        self.file = open(filename, 'wb')
        self.exporter = JsonItemExporter(self.file)

    def open_spider(self, spider):
        self.exporter.start_exporting()

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

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

其中 redefine_dir 和 dated_filename 是根据蜘蛛名称将序列化和文件放入正确目录的函数。

最终结果:前缀和序列化文件存储在所需目录中,没有爬虫错误,也无需忽略警告。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多