【问题标题】:Is there any method to using seperate scrapy pipeline for each spider?有什么方法可以为每个蜘蛛使用单独的scrapy管道吗?
【发布时间】:2013-06-29 14:29:56
【问题描述】:

我想获取不同域下的网页,这意味着我必须在命令“scrapy crawl myspider”下使用不同的蜘蛛。但是,由于网页的内容不同,我必须使用不同的管道逻辑将数据放入数据库。但是对于每个蜘蛛来说,它们都必须经过 settings.py 中定义的所有管道。是否有其他优雅的方法可以为每个蜘蛛使用单独的管道?

【问题讨论】:

  • Scrapy 本身并不将蜘蛛限制在单个域中。

标签: python web-scraping scrapy scrapy-spider


【解决方案1】:

ITEM_PIPELINES 设置是在引擎启动期间为项目中的所有蜘蛛全局定义的。不能即时更改每个蜘蛛。

以下是一些可供考虑的选项:

  • 更改管道的代码。在管道的process_item 方法中跳过/继续处理蜘蛛返回的项目,例如:

    def process_item(self, item, spider): 
        if spider.name not in ['spider1', 'spider2']: 
            return item  
    
        # process item
    
  • 改变开始爬行的方式。执行from a script,根据作为参数传递的蜘蛛名称,在调用crawler.configure() 之前覆盖您的ITEM_PIPELINES 设置。

另见:

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    上面的一个稍微好一点的版本如下。更好的是,这种方式可以让您有选择地为不同的蜘蛛打开管道,比上面的 'not in ['spider1','spider2']' in the pipeline 的编码更容易。

    在你的蜘蛛类中,添加:

    #start_urls=...
    pipelines = ['pipeline1', 'pipeline2'] #allows you to selectively turn on pipelines within spiders
    #...
    

    然后在每个管道中,您可以使用getattr 方法作为魔术。添加:

    class pipeline1():  
        def process_item(self, item, spider):
           if 'pipeline1' not in getattr(spider, 'pipelines'):
              return item
           #...keep going as normal  
    

    【讨论】:

      【解决方案3】:

      更强大的解决方案;不记得我在哪里找到它,但是一个scrapy开发人员在某个地方提出了它。使用这种方法可以让你在不使用包装器的情况下在所有蜘蛛上运行一些管道。它还使您不必重复检查是否使用管道的逻辑。

      包装器:

      def check_spider_pipeline(process_item_method):
          """
              This wrapper makes it so pipelines can be turned on and off at a spider level.
          """
          @functools.wraps(process_item_method)
          def wrapper(self, item, spider):
              if self.__class__ in spider.pipeline:
                  return process_item_method(self, item, spider)
              else:
                  return item
      
          return wrapper
      

      用法:

      @check_spider_pipeline
      def process_item(self, item, spider):
          ........
          ........
          return item
      

      蜘蛛用法:

      pipeline = {some.pipeline, some.other.pipeline .....}
      

      【讨论】:

      • 您好,可以举个例子吗?这个解决方案需要从命令行运行吗?
      猜你喜欢
      • 1970-01-01
      • 2015-11-07
      • 1970-01-01
      • 2015-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      • 1970-01-01
      相关资源
      最近更新 更多