Scrapy文档列出了所有the built-in methods of ItemLoader instances并解释了how to declare your own Item Loaders。但是,您声明的任何ItemLoader都将应用于所有已处理的项目。您可以使用Item Loader Contexts稍微修改他们的行为,但这通常不够精细。</ p>
假设我有一个Scrapy项目,其中所有Spider和所有项都继承相同的基本Spider和项目加载器,但这些Spider都包含具有一些通用功能的特定于站点的逻辑。在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, ..., ...)
尽管这似乎是扩展ItemLoader的一种显而易见的方法,就像您对其他任何类的扩展一样,但未记录该文档,并且在我检查过的任何地方(Google,StackOverflow),我都没有看到如何在Scrapy中执行此操作的示例。有可能/是否受支持,您将如何声明它们?
答案 0 :(得分:0)
有可能/是否受支持,您将如何声明它们?
有可能。哪种方法取决于您共享的逻辑类型。
您可以以与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))
或者,根据您在 some 蜘蛛共享的函数中所具有的实际逻辑,可以将简单的processor传递给add_*
方法去。
答案 1 :(得分:0)
您可以在 CustomItemLoader
文件中定义 items.py
类,您在其中定义了 Product
项目,如下所示:
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, ..., ...)