当检查传递到管道的项目类型时,Scrapy 给了我一个 scrapy.item.ItemMeta 类,而不是看似明显的类。
管道.py:
def process_item(self, item, spider):
print(type(item))
print(type(WikiItem))
上述语句产生
<class 'MyScrapers.items.WikiItem'>
<class 'scrapy.item.ItemMeta'>
为什么第二个 type() 语句不打印 WikiItem 的值,尽管明确传递了该类?我怎样才能使它们匹配?
附加信息
在管道中,有一个简单的 if 语句,使用 if isinstance() 语句根据传递的项目类型执行操作。条件永远不会满足。为了调试这个问题,我只需放置两个打印语句来打印传递到 Scrapy Pipeline 的项目类型以及正在检查的项目类型。
pipelines.py 中的导入语句
from openpyxl import Workbook
from items import ModelItem, WikiItem
items.py 中的导入语句
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())
...
在第一个
type()
语句中,您将打印项目实例的类型,它是 WikiItem
类的实例。这就是为什么它会打印 <class 'MyScrapers.items.WikiItem'>
。
type()
语句中,您将打印 WikiItem
类本身的类型,在 Scrapy 框架中由 ItemMeta
表示。当你定义像WikiItem
这样的Scrapy项目类时,Scrapy会为其生成一个metaclassItemMeta
,它负责创建项目类的实例。该元类是 Python 内置类型的子类。因此,当您打印 WikiItem
的类型时,它会显示 <class 'scrapy.item.ItemMeta'>
。
isinstance
:if isinstance(item, WikiItem): # do something
(请参阅下面的代码)。
我怎样才能使它们匹配?
如果您特别想与您的班级一起工作,则只需添加括号:
>>> from itemloaders.processors import TakeFirst
>>> from scrapy import Item, Field
>>>
>>> class WikiItem(Item):
... model_number = Field(default='', output_processor = TakeFirst())
...
>>> example_item=WikiItem()
>>> print(type(example_item))
<class '__main__.WikiItem'>
>>> print(type(WikiItem)) # without parenthesis
<class 'scrapy.item.ItemMeta'>
>>> print(type(WikiItem())) # with parenthesis
<class '__main__.WikiItem'>
>>> isinstance(example_item, WikiItem) # regular isinstance
True