如何创建一个输出处理器(Scrapy框架),它组成几个函数的输出,而不是在最终输出上得到“无”?

时间:2013-12-26 13:35:29

标签: python python-2.7 scrapy

我有这段代码:

items.py

class MyItem(Item):

    never_populated_field = Field()
    just_punctuation = Field()
    unwanted_text = Field()
    some_other_text = Field()

loaders.py

def eliminate_string_without_text(txt):
    if re.search(r'\w+', txt, flags=re.UNICODE) :
        return txt
    else:
        return None

def eliminate_unwanted_text(txt):
    if txt == 'Remove this text!' :
        return None
    else:
        return txt

class MyLoader(ItemLoader):

    default_input_processor = MapCompose(
                                    lambda x: u' '.join(x.split()),
                                    unicode.lower,
                                    eliminate_string_without_text,
                                    eliminate_unwanted_text)
    default_output_processor = Join()

它工作正常。

输入:(输入来自html文档,带有选择器。)

i = MyLoader(item=MyItem())
i.add_value('just_punctuation', [u'.?!', u' \n.'])
i.add_value('unwanted_text', [u'Remove  this \n text!'])
i.add_value('some_other_text', [u'let   me', u'on   output...'])

输出:

{'some_other_text': u'let me on output...'}

现在我的问题......
假设这个输入:

i = MyLoader(item=MyItem())
i.add_value('just_punctuation', [u'.?!', u' \n.'])
i.add_value('unwanted_text', [u'Remove  this \n'])
i.add_value('unwanted_text', [u' text', u'!'])
i.add_value('some_other_text', [u'let   me', u'on'])
i.add_value('some_other_text', [u'  output', u'...'])

我想要与上面相同的输出。但输出是:

{'some_other_text': u'let me on output',
 'unwanted_text': u'Remove this text'}

是对的。函数“eliminate_string_without_text”消除了“some_other_text”的“...”,并且函数“eliminate_unwanted_text”将永远不会消除任何东西,因为输入被分成几个部分。 因此,我需要在Join()之后将两个“消除”函数放在输出处理器上。我已经尝试了几件事,我仍然认为这应该有效:

default_input_processor = MapCompose(
                                lambda x: u' '.join(x.split()),
                                unicode.lower)
default_output_processor = Compose(
                                Join(),
                                eliminate_string_without_text,
                                eliminate_unwanted_text)

事实上,它有效:

{'just_punctuation': None,
 'never_populated_field': None,
 'some_other_text': u'let me on output...',
 'unwanted_text': None}

最后,如何在输出中没有“无”的情况下这样做? (我想要我给出的第一个输出示例。)我可以将两个“消除”函数作为项目管道,但我不想。我试图将它们更改为接收列表而不是字符串。我也读过了Loader的scrapy实现,但我是python的新手,我无法理解所有的东西是如何工作的。 实际上,当我只使用Join()时,我甚至不明白为什么输出上没有“无”?

谢谢!

(和副作用问题......当同一个字段有多个“add_value”时,处理的值是否与添加它们的顺序相同?)

更新:在我尝试@ user1147688的建议之前,我的代码已经发生了很大的变化。无论如何,根据https://github.com/scrapy/scrapy/pull/556,我认为这种行为在Scrapy 0.24.0上有所改变。

1 个答案:

答案 0 :(得分:0)

您必须将空列表(打印为“无”)转换为空字符串。尝试使用str()