Scrapy:Itemloader处理器/方法类型错误:“ ItemMeta”对象不可下标

时间:2019-05-01 07:47:00

标签: python python-3.x scrapy

我正在尝试构建在扩展的Itemloader类中使用的函数(clean_keyboard)。 它应该过滤和清除扩展项目类'category'='Notebook'中的数据。 我已经在没有“笔记本”->过滤器的情况下对其进行了测试(如果ProductItem ['category'] =='Notebook':),并且处理器/方法可以在没有该过滤器的情况下正常运行。但是插入这段代码进行过滤后,我在标题中得到了TypeError。请参见下面的代码。

非常感谢您提供解决此问题的帮助


### processor method for cleaning data with the Itemloader, Item and Itemloader class extended

def clean_keyboard(pattern):
    keyboard_dict = {'deutsch': 'DE', 'US-QWERTY': 'US', '': 'DE'} 

    if ProductItem['category'] == 'Notebook': # <-- TypeError when adding category filter, without it works fine
       if pattern in keyboard_dict:
            return keyboard_dict[pattern] 
        else:
            return pattern

class ProductItem(scrapy.Item):
    category = scrapy.Field()
    keyboard = scrapy.Field()

class SpiderItemLoader(ItemLoader):
    default_item_class = ProductItem
    default_input_processor = MapCompose(str.strip)
    default_output_processor = TakeFirst()

    keyboard_out = MapCompose(clean_keyboard)


### Parse Method in the Spider to get the data/ using the SpiderItemloader extended class

def parse_item(self, response):

    l = SpiderItemLoader(response = response)

    l.add_xpath('keyboard', '//*[@class="short-description"]/p/strong[text()="keyboard"]/following-sibling::text()')
    l.add_xpath('category', '//*[@class="short-description"]/p/strong[text()="category"]/following-sibling::text()'')

    return l.load_item()

2 个答案:

答案 0 :(得分:0)

正如丹尼尔(Daniel)所评论的那样,失败的话毫无意义。您想检查正在处理的项目的'category'属性,但是您的clean_keyboard函数无法访问它。 ProductItem是所有项目(而不是特定项目)共享的类。

项目加载器处理器无法访问项目,只能访问这些项目的特定属性。

我建议您使用item pipeline而不是项目加载器处理器来实现clean_keyboard函数的逻辑。

答案 1 :(得分:0)

的确,感谢你们俩通过类访问(Itemloader与Item Pipeline)帮助我理解了这一点。

因此,由于我确实有权访问Item Pipeline中的项目,因此能够解决过滤问题,并通过使用Item Pipeline访问其他项目。请参阅下面的解决方案,查看我经过测试的代码。

# Configure item pipelines in settings.py

ITEM_PIPELINES = {
   'tutorial.pipelines.DataCleaningPipeline': 300,
}

# Pipeline in pipelines.py

class DataCleaningPipeline(object):

    def process_item(self, item, spider):

        keyboard_dict = {'deutsch': 'DE', 'US-QWERTY': 'US', '': 'DE', 'QWERTZ': 'DE'} 

        dict_key = item.get('keyboard')
        category = item.get('category')

        if 'Notebook' in category and dict_key in keyboard_dict:
            item['keyboard']= keyboard_dict[dict_key]
            return item 
        else:
            return item