Scrapy管道Item类型匹配异常:为何返回ItemMeta而非自定义类?
Scrapy管道Item类型判断问题
问题描述
在Scrapy管道中检查Item类型时,发现打印type(WikiItem)得到的是scrapy.item.ItemMeta,而传入的item实例类型是MyScrapers.items.WikiItem,导致原本用isinstance()的类型判断始终不生效。
上下文代码与输出
管道中的排查代码
def process_item(self, item, spider): print(type(item)) print(type(WikiItem))
执行输出
<class 'MyScrapers.items.WikiItem'> <class 'scrapy.item.ItemMeta'>
相关代码片段
- pipelines.py导入语句:
from openpyxl import Workbook from items import ModelItem, WikiItem
- items.py中Item定义:
import scrapy import re from scrapy.loader import ItemLoader from itemloaders.processors import TakeFirst from scrapy import Item, Field # 其他代码... class WikiItem(Item): model_number = Field(default='', output_processor = TakeFirst()) # 其他代码...
原因与解决方法
原因
Scrapy的Item类是通过ItemMeta元类创建的,所以自定义Item类本身的类型是元类ItemMeta,而管道中传入的item是该类的实例,它的类型才是你定义的WikiItem类。
解决方法
不需要纠结类的类型,直接用isinstance()判断实例归属即可,这也是Scrapy中推荐的类型判断方式:
def process_item(self, item, spider): if isinstance(item, WikiItem): # 执行WikiItem对应的处理逻辑 print("处理WikiItem") elif isinstance(item, ModelItem): # 执行ModelItem对应的处理逻辑 print("处理ModelItem") # 必须返回item,否则后续管道无法处理 return item
如果需要严格匹配类型(不考虑继承),可以直接对比实例的类型和目标类:
def process_item(self, item, spider): if type(item) is WikiItem: # 处理逻辑 pass return item
内容的提问来源于stack exchange,提问作者Josh Ribeiro
相关产品推荐
相关产品推荐

