我认为我的问题是由对某些scrapy
概念的误解引起的。如果有人可以向我解释这一点,我将感激不尽。
让我们想象一下我有以下蜘蛛:
# -*- coding: utf-8 -*-
import scrapy
from scrapy.loader import ItemLoader
from reddit.items import RedditItem
from scrapy.loader.processors import TakeFirst
class RedditspiderSpider(scrapy.Spider):
name = "redditspider"
allowed_domains = ["wwww.reddit.com"]
start_urls = [
'https://www.reddit.com/r/starcraft/comments/5t8v7i/community_feedback_update_widow_mines_carriers/?st=iz7ba37h&sh=b7e9bd35']
def parse(self, response):
l = ItemLoader(item=RedditItem(), response=response)
comments = response.xpath(
'//div[contains(@class,"usertext-body may-blank-within md-container ")]/div')
comments = comments[1:]
for comment_it in comments:
comment = comment_it.extract()
l.add_value('comment', comment)
yield l.load_item()
以下列方式定义RedditItem
:
from scrapy.item import Item, Field
from w3lib.html import remove_tags
from scrapy.loader.processors import TakeFirst
def _remove_tags(input):
return input
class RedditItem(Item):
comment = Field(input_processor=_remove_tags, output_processor=TakeFirst())
所以一切都简单明了。现在,我的问题。在第一个代码示例中,l
加载器具有字段comments
。据我所知,当我l.add_value('comment', comment)
时,会触发此字段的输入处理器。 这是正确的吗?
据我所知,这是正确的。在l.add_value('comment', comment)
comment
中是字符串,而不是列表。但是,当我在_remove_tags
中设置断点时,我发现input
实际上是长度为1的列表。所以我的主要问题是它为什么会发生?为什么我会通过一个字符串并在那里看到一个列表?
我查看了scrapy源代码,发现这是_add_value
(第90行):value = arg_to_iter(value)
。这使事情变得非常清楚,这似乎是我在那里看到长度1列表的原因。
这条线背后的设计理由是什么?这是因为在scrapy
我可以在不同的xpath / css请求中填充项目中的相同字段吗?如果是这样,那对我来说是有道理的。然后问题是:我该如何解决这个问题?我只是在输入处理器中应用map(_remove_tags, input)
吗?这会是一个推荐的解决方案还是我出错了?
由于
答案 0 :(得分:2)
是的,scrapy加载器设计用于处理同一领域中的多个插入,您可以使用以下方法进行测试:
from scrapy.loader.processors import Identity
class RedditItem(Item):
comment = Field(input_processor=Identity(), output_processor=Identity())
l = ItemLoader(item=RedditItem(), response=response)
l.add_value('comment', 'first comment')
l.add_value('comment', 'second comment')
print l.output_value('comment') # ['first comment', 'second comment']
现在,正因为如此,您可以检查here scrapy程序员使用的输入和输出(default_output_processor
和default_input_processor
内部)的推荐处理器。
正如您所看到的,他们有一个名为MapCompose
的处理器,它接受当前值的每个条目并应用定义为参数的每个方法。