Scrapy 文档列出了 ItemLoader 实例的所有内置方法,并解释了如何声明自己的 Item Loader。但是,您声明的任何条目加载器都将应用于所有已处理的项目。您可以使用条目加载器上下文稍微修改它们的行为,但这通常不够精细。
假设我有一个 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 的明显方法,就像您为任何其他类所做的那样,但它没有记录在案,而且我在我检查过的任何地方都没有看到如何在 Scrapy 中执行此操作的示例(Google、StackOverflow)。是否可能/支持,您将如何声明它们?
是否可能/支持,您将如何声明它们?
这是可能的。哪种方式取决于您共享的逻辑类型。
你可以以与 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_*
方法的简单处理器可能是要走的路。
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, ..., ...)