【问题标题】:saving scraped items to json/csv/xml file using scrapy使用 scrapy 将抓取的项目保存到 json/csv/xml 文件
【发布时间】:2014-02-28 16:41:45
【问题描述】:

我正在从他们的official doc 学习Scrapy(一个网络爬虫框架)。
通过以下示例和文档,我创建了我的蜘蛛来使用站点地图抓取数据

from scrapy.contrib.spiders import SitemapSpider
from scrapy.selector import Selector
from MyProject1.items import MyProject1Item

class MySpider(SitemapSpider):
    name="myspider"
    sitemap_urls = ['http://www.somesite.com/sitemap.xml']
    sitemap_follow = ['/sitemapbrowsesection\d+']
    count=0
    def parse(self, response):
        self.count=self.count+1
        item=MyProject1Item()
        sel=Selector(response)
        item["exp"]=sel.xpath('/html/head/title/text()').extract()
        print str(self.count)+":\t"+response.url
        print sel.xpath('/html/head/title/text()').extract()
        print "\n\n"

我可以通过运行命令在屏幕上看到带有日志的抓取结果
scrapy crawl myspider
我可以通过在命令中添加选项将抓取的结果保存到 json/csv/xml 文件
scrapy crawl myspider -o item.json -t json 以在json 文件中获取结果。

我的问题是,只有当scrapy 完成爬行时,scrapy 才会将抓取的结果转储到 item.json。意味着必须等到爬行结束。所以对于大型项目我将不得不等待很长时间,因为我猜scrapy会在完成所有爬取后将抓取结果写入json文件。

我希望 scrapy 立即或几乎立即或在抓取过程中写入 json 文件,以便在 scrapy 运行时查看已抓取网站的结果。

我知道scrapy中一定有一些我无法捕捉到的东西。我试图从http://doc.scrapy.org/en/latest/topics/feed-exports.html获得帮助

http://doc.scrapy.org/en/latest/topics/exporters.html
但无法解决我的问题。所以我正在寻找一些帮助或示例代码,否则我必须在 parse(self, response) 函数中添加几行来创建 json/csv 文件并将报废的结果写入其中。

【问题讨论】:

    标签: python scrapy


    【解决方案1】:

    这就是写入文件的工作方式。有一个缓冲区只有在满时才会写入磁盘。

    例如,在一个 shell 中用 python 打开一个文件:

    $ ipython
    
    In [1]: fp = open('myfile', 'w')
    

    在另一个shell中监控文件内容:

    $ tail -f myfile
    

    回到python shell,写一些内容:

    In [2]: _ = [fp.write("This is my file content\n") for i in range(100)]
    

    就我而言,我在tail 输出中看不到任何内容。写更多内容:

    In [3]: _ = [fp.write("This is my file content\n") for i in range(100)]
    

    现在我看到了tail 输出中的行。

    实际上,您可以更改文件缓冲(参见 [1])。再次打开一个文件:

    $ ipython
    
    In [1]: fp = open('myfile', 'w', buffering=0)
    

    在另一个shell中监控文件内容:

    $ tail -f myfile
    

    写点东西看看tail的输出:

    In [2]: fp.write("Hello there\n")
    

    最好启用缓冲(减少磁盘 I/O)。您的项目文件最终将获得输出,但您可能希望将格式更改为默认的jsonlines(不需要-t 参数),这样您每行都会获得一个json 对象。这是一种高度使用的流媒体格式。

    您可以轻松阅读jsonlines.jl 扩展名):

    import json
    
    for line in open('items.jl'):
        data = json.loads(line)
        # do stuff with data
    

    甚至还有其他工具,例如 head + json.tooljq(参见 [2]):

    $ head -1 items.jl | python -m json.tool
    $ jq -I . items.jl
    

    到目前为止,我还没有看到任何问题,我将项目写入.jl 文件(或任何其他格式)。然而,如果您的工作被杀死,您将丢失缓冲区中的最后一项。这可以通过将项目存储在数据库或类似的东西中来解决。

    [1]http://docs.python.org/2/library/functions.html#open

    [2]http://stedolan.github.io/jq/manual/

    【讨论】:

    • 我会简化答案并坚持为 OP 用例推荐 JSON Lines。
    【解决方案2】:

    scrapy crawl myspider -o item.json -t json 仅在抓取时保存获取的结果。我不必等待爬行完成。我可以在爬虫运行时看到文件 item.json 的内容

    所以不需要包含将获取的数据写入蜘蛛文件的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-12
      • 1970-01-01
      • 1970-01-01
      • 2017-05-01
      • 2019-03-25
      • 2016-03-02
      • 2020-10-11
      • 1970-01-01
      相关资源
      最近更新 更多