Scrapy: Itemloader Processor / Method TypeError: объект ItemMeta не может быть подписан - PullRequest
0 голосов
/ 01 мая 2019

Я пытаюсь создать функцию (clean_keyboard) для использования в расширенном классе Itemloader. Он должен фильтровать и очищать данные в расширенном классе предметов 'category' = 'Notebook'. Я проверил его без фильтра для «Записных книжек» -> (если ProductItem ['category'] == 'Записная книжка' :), а Процессор / Метод работает без проблем. Но после вставки этого фрагмента кода для фильтрации я получаю ошибку 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 голосов
/ 02 мая 2019

Действительно, спасибо вам обоим за помощь в понимании этого с доступом к классу (Itemloader vs. 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

0 голосов
/ 02 мая 2019

Как прокомментировал Даниэль, неудачная линия не имеет смысла.Вы хотите проверить свойство 'category' обрабатываемого элемента, однако ваша функция clean_keyboard не имеет к нему доступа.ProductItem - это класс, общий для всех элементов, а не для конкретного элемента.

Процессоры загрузчика элементов не имеют доступа к элементам, только к определенным их свойствам.

Я рекомендую использовать конвейер элементов вместо процессора загрузчика элементов для реализации логики вашей функции clean_keyboard.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...