scrapy 蜘蛛完成后重命名输出文件

Rename output file after scrapy spider complete

我正在使用 Scrapy 和 Scrapyd 来监控某些网站。输出文件是压缩的 jsonlines。在我向 scrapyd 提交工作计划后,我可以看到正在创建的输出文件,并且随着它的抓取而增长。

我的问题是我无法确定输出文件何时准备就绪,即蜘蛛是否已完成。一种方法是将输出文件重命名为 "output.done" 这样我的其他程序可以列出这些文件并处理它们。

我目前的方法是查看文件的修改时间,如果五分钟内没有变化就认为完成了。不过,有时候5分钟好像不够用,真希望不要再延长到30分钟了。

您可能希望使用 scrapy 信号,特别是 spider_openedspider_closed 来了解蜘蛛何时使用该文件。可以在此处找到更多信息:http://doc.scrapy.org/en/latest/topics/signals.html

spider_opened 可以将文件重命名为 output.progressspider_closed 可以将其重命名为 output.done 表示蜘蛛不再使用该文件。

如果输出文件由 Item 管道写入,则可以使用 open_spiderclose_spider 回调,这与使用信号的逻辑相同。有关项目管道回调的更多信息:http://doc.scrapy.org/en/latest/topics/item-pipeline.html#writing-your-own-item-pipeline.

在尝试了不同的方法后,我得到了一个可行的解决方案。 因为在我的特殊情况下,我将输出转储到文件中,特别是 bz2 文件。我自定义了一个 FileFeedStorage 来完成打开文件之前和关闭文件之后的工作。请参阅下面的代码:

from scrapy.contrib.feedexport import FileFeedStorage
import os
import bz2

MB = 1024 * 1024


class Bz2FileFeedStorage(FileFeedStorage):
  IN_PROGRESS_MARKER = ".inprogress"

  def __init__(self, uri):
    super(Bz2FileFeedStorage, self).__init__(uri)
    self.in_progress_file = self.path + Bz2FileFeedStorage.IN_PROGRESS_MARKER

  def open(self, spider):
    dirname = os.path.dirname(self.path)
    if dirname and not os.path.exists(dirname):
      os.makedirs(dirname)
    return bz2.BZ2File(self.in_progress_file, "w", 10 * MB)

  def store(self, file):
    super(Bz2FileFeedStorage, self).store(file)
    os.rename(self.in_progress_file, self.path)