【问题标题】:Extend a Scrapy ItemLoader with custom methods使用自定义方法扩展 Scrapy ItemLoader
【发布时间】:2019-06-26 20:46:17
【问题描述】:

Scrapy 文档列出了所有the built-in methods of ItemLoader instances 并解释了how to declare your own Item Loaders。但是,您声明的任何 ItemLoaders 都将适用于所有已处理的项目。您可以使用 Item Loader Contexts 稍微修改他们的行为,但这通常不够精细。

假设我有一个 Scrapy 项目,其中蜘蛛和项目都继承了相同的基础蜘蛛和项目加载器,但蜘蛛都包含特定于站点的逻辑和一些常用功能。我在 Scrapy 文档中没有提到向 ItemLoaders 添加类方法,而不是:

import mymodule

class MySpider(BaseSpiderName):
  def parse_item(self, response):
    product = ItemLoader(item=Product(), response=response)
    new_value = mymodule.myfunction(argument, ..., ...)
    product.add_value('my_field', new_value)

你可以写:

# (no extra import)
class MySpider(BaseSpiderName):
  def parse_item(self, response):
    product = CustomItemLoader(item=Product(), response=response)
    product.custom_function(argument, ..., ...)

尽管这似乎是扩展 ItemLoaders 的一种显而易见的方法,就像您对任何其他类所做的那样,但它没有记录在案,而且我在我检查过的任何地方(Google、StackOverflow)都没有看到如何在 Scrapy 中执行此操作的示例。是否可能/受支持,您将如何声明它们?

【问题讨论】:

    标签: python scrapy


    【解决方案1】:

    是否可能/受支持,您将如何声明它们?

    这是可能的。采用哪种方式取决于您共享的逻辑类型。

    您可以以与 Scrapy 无关的方式声明您的方法,即就像您对任何其他 Python 类所做的那样:子类化您的 CustomItemLoader 类并在该子类中定义方法:

    from scrapy.loaders import ItemLoader
    
    class CustomItemLoader(ItemLoader):
    
        def custom_function(self, *args, **kwargs):
            self.add_value('my_field', mymodule.myfunction(*args, **kwargs))
    

    或者,根据您在 一些 蜘蛛共享的函数中的实际逻辑,您传递给您的 add_* 方法的简单 processor 可能是要走的路。

    【讨论】:

      【解决方案2】:

      您可以在您定义Product 项目的items.py 文件中定义CustomItemLoader 类,如下所示:

      from scrapy import Item, Field
      from scrapy.loader import ItemLoader
      from scrapy.loader.processors import MapCompose, TakeFirst
      
      class CustomItemLoader(ItemLoader):
          default_output_processor = TakeFirst()
          
          def custom_function(argument1, argument2, argument3):
              # your custom function logic goes here..
              pass
      
      
      class Product(Item):
          # define the fields for your item here like:
          pass
      

      然后你可以在你的蜘蛛代码中使用CustomItemLoader.. 像这样:

      from <PROJECT-NAME>.items import CustomItemLoader, Product
      
      class MySpider(BaseSpiderName):
         def parse_item(self, response):
            product = CustomItemLoader(item=Product(), response=response)
            product.custom_function(argument, ..., ...)
      

      【讨论】:

        猜你喜欢
        • 2012-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-12
        • 1970-01-01
        • 1970-01-01
        • 2017-12-02
        • 1970-01-01
        相关资源
        最近更新 更多