scrapy 蜘蛛完成后重命名输出文件
Rename output file after scrapy spider complete
我正在使用 Scrapy 和 Scrapyd 来监控某些网站。输出文件是压缩的 jsonlines。在我向 scrapyd 提交工作计划后,我可以看到正在创建的输出文件,并且随着它的抓取而增长。
我的问题是我无法确定输出文件何时准备就绪,即蜘蛛是否已完成。一种方法是将输出文件重命名为 "output.done" 这样我的其他程序可以列出这些文件并处理它们。
我目前的方法是查看文件的修改时间,如果五分钟内没有变化就认为完成了。不过,有时候5分钟好像不够用,真希望不要再延长到30分钟了。
您可能希望使用 scrapy 信号,特别是 spider_opened
和 spider_closed
来了解蜘蛛何时使用该文件。可以在此处找到更多信息:http://doc.scrapy.org/en/latest/topics/signals.html
spider_opened
可以将文件重命名为 output.progress 而 spider_closed
可以将其重命名为 output.done 表示蜘蛛不再使用该文件。
如果输出文件由 Item 管道写入,则可以使用 open_spider
和 close_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)
我正在使用 Scrapy 和 Scrapyd 来监控某些网站。输出文件是压缩的 jsonlines。在我向 scrapyd 提交工作计划后,我可以看到正在创建的输出文件,并且随着它的抓取而增长。
我的问题是我无法确定输出文件何时准备就绪,即蜘蛛是否已完成。一种方法是将输出文件重命名为 "output.done" 这样我的其他程序可以列出这些文件并处理它们。
我目前的方法是查看文件的修改时间,如果五分钟内没有变化就认为完成了。不过,有时候5分钟好像不够用,真希望不要再延长到30分钟了。
您可能希望使用 scrapy 信号,特别是 spider_opened
和 spider_closed
来了解蜘蛛何时使用该文件。可以在此处找到更多信息:http://doc.scrapy.org/en/latest/topics/signals.html
spider_opened
可以将文件重命名为 output.progress 而 spider_closed
可以将其重命名为 output.done 表示蜘蛛不再使用该文件。
如果输出文件由 Item 管道写入,则可以使用 open_spider
和 close_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)