2015-10-15 152 views
5

有没有办法覆盖所述文件而不是附加它?Scrapy覆盖json文件而不是附加文件

实施例)

scrapy crawl myspider -o "/path/to/json/my.json" -t json  
scrapy crawl myspider -o "/path/to/json/my.json" -t json 

将追加my.json文件,而不是覆盖它。

回答

9
scrapy crawl myspider -t json --nolog -o - > "/path/to/json/my.json" 
+0

谢谢!这是我正在寻找的。所以简单的“ - >”部分覆盖文件? – hooliooo

+0

-o - :重定向到标准输出,并>将标准输出重定向到具有以下路径的新文件。我用它并奇怪地工作,就像我得到无效的JSON输出。 – miguelfg

+0

当我在Docker容器内使用subprocess.check_output调用它时,为什么这不起作用? '''','>','''','''','''','''''''''''''''''''''' ,'-a','url = url.jpg]'返回非零退出状态2 – 2017-05-18 09:27:37

2

这是Scrapy的一个旧的well-known "problem"。每次你开始爬行,你不想保留以前调用的结果,你必须删除文件。这背后的想法是,您想要在不同的时间范围内抓取不同的网站或同一网站,以免意外丢失已收集的结果。这可能是不好的。

解决方案是编写一个自己的物品管道,您可以在其中打开目标文件'w'而不是'a'

要了解如何在文档写一个这样的管道看看:http://doc.scrapy.org/en/latest/topics/item-pipeline.html#writing-your-own-item-pipeline(专门为JSON出口:http://doc.scrapy.org/en/latest/topics/item-pipeline.html#write-items-to-a-json-file

+0

我可以使用exporter.py脚本来做类似的事情吗?我用我的编辑实例化一个自定义的JsonItemExporter类? (我还是一个新手程序员,所以我不知道我说的是否正确),然后添加self.file = open(file,'wb')?我不确定这是否是正确的方式 – hooliooo

0

,因为公认的答案给了我unvalid JSON的问题,这可能是工作:

find "/path/to/json/" -name "my.json" -exec rm {} \; && scrapy crawl myspider -t json -o "/path/to/json/my.json" 
6

为了解决这个问题,我在myproject目录中创建了一个scrapy.extensions.feedexport.FileFeedStorage的子类。

这是我customexport.py

"""Custom Feed Exports extension.""" 
import os 

from scrapy.extensions.feedexport import FileFeedStorage 


class CustomFileFeedStorage(FileFeedStorage): 
    """ 
    A File Feed Storage extension that overwrites existing files. 

    See: https://github.com/scrapy/scrapy/blob/master/scrapy/extensions/feedexport.py#L79 
    """ 

    def open(self, spider): 
     """Return the opened file.""" 
     dirname = os.path.dirname(self.path) 
     if dirname and not os.path.exists(dirname): 
      os.makedirs(dirname) 
     # changed from 'ab' to 'wb' to truncate file when it exists 
     return open(self.path, 'wb') 

然后我说下面我settings.py(参见:https://doc.scrapy.org/en/1.2/topics/feed-exports.html#feed-storages-base):

FEED_STORAGES_BASE = { 
    '': 'myproject.customexport.CustomFileFeedStorage', 
    'file': 'myproject.customexport.CustomFileFeedStorage', 
} 

现在,每当我写一个文件时,它就会被改写,因为这个。

+0

很好的解决方案。在settings.py中重新定义FEED_STORAGES_BASE是一个好主意吗?在这种情况下,scrapy crawl命令仍然会面临这个问题。 – hAcKnRoCk

+0

我会称之为'OverwriteFileFeedStorage'。 – Suor