【问题标题】:How can scrapy export items to separate csv files per itemscrapy 如何将项目导出为每个项目单独的 csv 文件
【发布时间】:2012-08-27 03:45:01
【问题描述】:

我正在抓取一个足球网站,而蜘蛛(单个蜘蛛)从该网站的页面中获取多种项目:球队、比赛、俱乐部等。 我正在尝试使用 CSVItemExporter 将这些项目存储在单独的 csv 文件中, team.csv、matches.csv、clubs.csv 等

我不确定这样做的正确方法是什么。 到目前为止,我想到的唯一方法是创建我自己的自定义管道,就像在示例中一样 http://doc.scrapy.org/en/0.14/topics/exporters.html 并在 spider_opened 方法中打开所有需要的 csv 文件,即为每个 csv 文件创建一个 csv 导出器,并在 process_item 中放置代码以确定“item”参数是哪种项目,然后将其发送到相应的出口商对象。

无论如何,我还没有找到在 scrapy 中处理多个 csv 文件(每个项目类型)的任何示例,所以我担心我正在以一种不应该使用的方式使用它。 (这是我第一次使用 Scrapy)。

二元组

【问题讨论】:

    标签: csv scrapy exporter


    【解决方案1】:

    你的方法对我来说似乎很好。 Piplines 是 Scrapy 的一个很棒的功能,并且是 IMO 为类似您的方法而构建的。

    您可以创建多个项目(例如 SoccerItem、MatchItem)并在您的 MultiCSVItemPipeline 中通过检查项目类将每个项目委托给其自己的 CSV 类。

    【讨论】:

    • 好的,写完 MultiCSVItemPipeline 我感觉好多了:-)。我检查了您建议的项目类别,以确定项目的去向。我正在给出一个自我答案,以向有相同问题的任何人展示代码。
    • @Diomedes - 您能否分享一下 items.py、蜘蛛代码和 settings.py 的代码。这将非常有帮助。因为我使用以下相同的代码将 csv 文件设为空。对我来说 Scrapy 版本是 1.8.0。谢谢
    【解决方案2】:

    我在这里发布了我用来根据上面 drcolossos 的回答生成MultiCSVItemPipeline 的代码。

    此管道假定所有 Item 类都遵循约定 *Item(例如 TeamItem、EventItem)并创建 team.csv、event.csv 文件并将所有记录发送到适当的 csv 文件。

    from scrapy.exporters import CsvItemExporter
    from scrapy import signals
    from scrapy.xlib.pydispatch import dispatcher
    
    
    def item_type(item):
        return type(item).__name__.replace('Item','').lower()  # TeamItem => team
    
    class MultiCSVItemPipeline(object):
        SaveTypes = ['team','club','event', 'match']
        def __init__(self):
            dispatcher.connect(self.spider_opened, signal=signals.spider_opened)
            dispatcher.connect(self.spider_closed, signal=signals.spider_closed)
    
        def spider_opened(self, spider):
            self.files = dict([ (name, open(CSVDir+name+'.csv','w+b')) for name in self.SaveTypes ])
            self.exporters = dict([ (name,CsvItemExporter(self.files[name])) for name in self.SaveTypes])
            [e.start_exporting() for e in self.exporters.values()]
    
        def spider_closed(self, spider):
            [e.finish_exporting() for e in self.exporters.values()]
            [f.close() for f in self.files.values()]
    
        def process_item(self, item, spider):
            what = item_type(item)
            if what in set(self.SaveTypes):
                self.exporters[what].export_item(item)
            return item
    

    【讨论】:

    • 能否请您包含导入某些模块的代码?
    • 调度器是干什么用的?
    【解决方案3】:

    我已经尝试了答案。它似乎在最新版本(2.21)中不起作用。

    我已包含我的代码供您参考:

    class MultiCSVItemPipeline(object):
        SaveTypes = ['CentalineTransactionsItem','CentalineTransactionsDetailItem','CentalineBuildingInfo']
    
        def open_spider(self, spider):
            self.files = dict([ (name, open(name+'.csv','w+b')) for name in self.SaveTypes ])
            self.exporters = dict([ (name,CsvItemExporter(self.files[name])) for name in self.SaveTypes])
            [e.start_exporting() for e in self.exporters.values()]
    
        def close_spider(self, spider):
            [e.finish_exporting() for e in self.exporters.values()]
            [f.close() for f in self.files.values()]
    
        def process_item(self, item, spider):
            what = type(item).__name__
            if what in set(self.SaveTypes):
                self.exporters[what].export_item(item)
            return item
        
    

    【讨论】:

      【解决方案4】:

      我正在使用 Scrapy = "^2.5.0" 并且必须进行一些修改才能正常工作。我还为项目文件中的所有项目设置了 SaveTypes(现在为 defined_items)动态。

      from scrapy.exporters import CsvItemExporter
      from YOUR_PROJECT import items
      
      
      def item_type(item):
          return type(item).__name__
      
      
      class MultiCSVItemPipeline(object):
          defined_items = [name for name, _ in items.__dict__.items() if "Item" in name]
      
          def open_spider(self, spider):
              self.files = dict(
                  [
                      (name, open("FOLDER_TO_SAVE/" + name + ".csv", "w+b"))
                      for name in self.defined_items
                  ]
              )
              self.exporters = dict(
                  [(name, CsvItemExporter(self.files[name])) for name in self.defined_items]
              )
              [e.start_exporting() for e in self.exporters.values()]
      
          def close_spider(self, spider):
              [e.finish_exporting() for e in self.exporters.values()]
              [f.close() for f in self.files.values()]
      
          def process_item(self, item, spider):
              item_name = item_type(item)
              if item_name in set(self.defined_items):
                  self.exporters[item_name].export_item(item)
              return item
      

      【讨论】:

        【解决方案5】:

        这是我用来利用scrapy 的Item Pipline 和Exporters 来为每个被抓取的Item 类类型输出一个单独的csv 的代码。逻辑与this example 非常相似。

        from scrapy.exporters import CsvItemExporter
        
        class cvs_per_itemtype_Pipeline:
        
            def open_spider(self, spider):
                self.itemType_to_exporterAndCsvFile = {}     
        
            def process_item(self, item, spider):
                itemType = type(item).__name__ #item class name as str
                if itemType not in self.itemType_to_exporterAndCsvFile:
                    csvFile = open(f'{itemType}.csv', 'wb')
                    exporter = CsvItemExporter(csvFile)
                    exporter.start_exporting()
                    self.itemType_to_exporterAndCsvFile[itemType] = (exporter, csvFile)
                exporter = self.itemType_to_exporterAndCsvFile[itemType][0]
                exporter.export_item(item)
                return item
        
            def close_spider(self, spider):
                for exporter, csvFile in self.itemType_to_exporterAndCsvFile.values():
                    exporter.finish_exporting()
                    csvFile.close()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-10-09
          • 1970-01-01
          • 2011-10-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-11
          • 1970-01-01
          相关资源
          最近更新 更多