检查传递到管道的项目类型 - scrapy.item.ItemMeta

问题描述 投票:0回答:1

短期问题

当检查传递到管道的项目类型时,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())

...
web-scraping scrapy scrapy-pipeline
1个回答
0
投票

在第一个

type()
语句中,您将打印项目实例的类型,它是
WikiItem
类的实例。这就是为什么它会打印
<class 'MyScrapers.items.WikiItem'>


在第二个
type()
语句中,您将打印
WikiItem
类本身的类型,在 Scrapy 框架中由
ItemMeta
表示。当你定义像
WikiItem
这样的Scrapy项目类时,Scrapy会为其生成一个metaclass
ItemMeta
,它负责创建项目类的实例。该元类是 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
© www.soinside.com 2019 - 2024. All rights reserved.