【问题标题】:Why are my input/output processors in Scrapy not working?为什么我在 Scrapy 中的输入/输出处理器不工作?
【发布时间】:2016-05-16 02:23:59
【问题描述】:

我正在尝试关注this tutorial

我希望我的 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,这样你就可以根据需要尝试修改它。

【问题讨论】:

  • 你希望发生什么?
  • 我希望desc 字段看起来像这样:“- DAVID MERTZ;ADDISON WESLEY。正在预订,全文,ASCII 格式。请求反馈。[作者网站,GNOSIS 软件, INC.]"

标签: python python-3.x scrapy


【解决方案1】:

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

我怀疑文档有误导/错误(或者可能已经过时?),因为根据源代码,input_processor 字段属性读取为only inside the ItemLoader instance,这意味着您需要使用一个 Item无论如何装载机。

您可以使用内置的并保留您的 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()

【讨论】:

  • 我明白了。现在我看了一下,我认为“声明输入和输出处理器”下的第二个代码 sn-p 确实暗示需要使用 ItemLoader,尽管它可能更明确。
【解决方案2】:

我解决它的方法是在你的 Scrapy 项目中实现一个管道,这样你就不必弄乱你现有的代码了。

piplines.py

class DmozPipeline(object):

    def process_item(self, item, spider):

        item['desc'] = ''.join(item['desc'].split()).upper()

    return item

别忘了在settings.py中激活管道

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-16
    • 2020-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多