为什么我在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-输入和输出处理器

项目.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': ['rntrn                                ',
          ' rn'
          'tttrn'
          '                                - By David Mertz; Addison Wesley. '
          'Book in progress, full text, ASCII format. Asks for feedback. '
          '[author website, Gnosis Software, Inc.]rn'
          '                                rn'
          '                                ',
          'rn                                '],
 'link': ['http://gnosis.cx/TPiP/'],
 'title': ['Text Processing in Python']}

我做错了什么?

我使用的是Python 3.5.1和Scrapy 1.1.0

我把我的全部代码放在这里:https://github.com/prashcr/scrapy_tutorial,以便您可以根据自己的意愿尝试和修改它。

但是,还有一个地方可以指定要使用的输入和输出处理程序:在项目字段元数据中。

我怀疑文档有误导性/错误(或者可能已经过时?),因为根据源代码,input_processor字段属性在ItemLoader实例中是只读的,这意味着您无论如何都需要使用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_processoroutput_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()

我修复它的方法是在你的Scrapy项目中实现一个管道,这样你就不必破坏现有的代码。

管道.py

class DmozPipeline(object):
    def process_item(self, item, spider):
        item['desc'] = ''.join(item['desc'].split()).upper()
    return item

别忘了激活设置中的管道.py

https://docs.scrapy.org/en/latest/topics/item-pipeline.html

最新更新