2016-05-16 1 views
4

Я пытаюсь следовать this tutorial.Почему мои процессоры ввода/вывода в Scrapy не работают?

Я хочу, чтобы мое поле desc было единственной строкой, нормированной на отдельные пробелы и в верхнем регистре.

dmoz_spider.py

import scrapy 
from tutorial.items import DmozItem 

class DmozSpider(scrapy.Spider): 
    name = "dmoz" 
    allowed_domains = ["dmoz.org"] 
    start_urls = [ 
     "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/", 
     "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/" 
    ] 

    def parse(self, response): 
     for sel in response.xpath('//ul/li'): 
      item = DmozItem() 
      item['title'] = sel.xpath('a/text()').extract() 
      item['link'] = sel.xpath('a/@href').extract() 
      item['desc'] = sel.xpath('text()').extract() 
      yield item 

Я попытался декларирование ввода/вывода процессоров в соответствии с http://doc.scrapy.org/en/latest/topics/loaders.html#declaring-input-and-output-processors

items.py

import scrapy 
from scrapy.loader.processors import MapCompose, Join 

class DmozItem(scrapy.Item): 
    title = scrapy.Field() 
    link = scrapy.Field() 
    desc = scrapy.Field(
     input_processor=MapCompose(
      lambda x: ' '.join(x.split()), 
      lambda x: x.upper() 
     ), 
     output_processor=Join() 
    ) 

Однако, мой выход по-прежнему оказывается, как это.

{'desc': ['\r\n\t\r\n        ', 
      ' \r\n' 
      '\t\t\t\r\n' 
      '        - By David Mertz; Addison Wesley. ' 
      'Book in progress, full text, ASCII format. Asks for feedback. ' 
      '[author website, Gnosis Software, Inc.]\r\n' 
      '        \r\n' 
      '        ', 
      '\r\n        '], 
'link': ['http://gnosis.cx/TPiP/'], 
'title': ['Text Processing in Python']} 

Что я делаю неправильно?

Я использую Python 3.5.1 и Scrapy 1.1.0

Я терплю весь свой код здесь: https://github.com/prashcr/scrapy_tutorial, так что вы можете попытаться изменить его, как вы хотите.

+0

Что вы ожидаете, что это произойдет? –

+0

Я ожидал, что поле 'desc' будет выглядеть так:" - BY DAVID MERTZ, ADDISON WESLEY. КНИГА В ПРОГРЕССЕ, ПОЛНЫЙ ТЕКСТ, ФОРМАТ ASCII. ЗАДАЕТСЯ ДЛЯ ОБРАТНОЙ СВЯЗИ. [АВТОРСКИЙ ВЕБ-САЙТ, ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ GNOSIS, INC.] " –

ответ

4

Однако есть еще одно место, где вы можете указать процессоры ввода и вывода для использования: в метаданных поля Элемент.

Я подозреваю, что документация вводит в заблуждение/неправильно (или может устареть?), Потому что, в соответствии с исходным кодом, атрибут input_processor поле читается only inside the ItemLoader instance, что означает, что вы должны использовать Item Loader так или иначе.

Вы можете использовать встроенный в одном и оставить DmozItem определение как:

from scrapy.loader import ItemLoader 

class DmozSpider(scrapy.Spider): 
    # ... 

    def parse(self, response): 
     for sel in response.xpath('//ul/li'): 
      loader = ItemLoader(DmozItem(), selector=sel) 
      loader.add_xpath('title', 'a/text()') 
      loader.add_xpath('link', 'a/@href') 
      loader.add_xpath('desc', 'text()') 
      yield loader.load_item() 

Таким образом, аргументы Пункт полевой input_processor и output_processor будут приняты во внимание и процессоры будут применяться.


Или вы можете определить процессоры внутри пользовательского элемента погрузчика вместо Item класса:

class DmozItem(scrapy.Item): 
    title = scrapy.Field() 
    link = scrapy.Field() 
    desc = scrapy.Field() 


class MyItemLoader(ItemLoader): 
    desc_in = MapCompose(
     lambda x: ' '.join(x.split()), 
     lambda x: x.upper() 
    ) 

    desc_out = Join() 

и использовать его для загрузки товаров в паука:

def parse(self, response): 
    for sel in response.xpath('//ul/li'): 
     loader = MyItemLoader(DmozItem(), selector=sel) 
     loader.add_xpath('title', 'a/text()') 
     loader.add_xpath('link', 'a/@href') 
     loader.add_xpath('desc', 'text()') 
     yield loader.load_item() 
+0

I видеть. Теперь, когда я смотрю на это, я думаю, что второй фрагмент кода в разделе «Объявление входных и выходных процессоров» подразумевал необходимость использования ItemLoader, хотя он мог быть более явным. –

Смежные вопросы