ItemLoader为什么从一个元素创建一个列表
我认为我的问题是由一些对某些scrapy
概念的误解造成的。所以我会很感激,如果有人能够向我解释这一点。ItemLoader为什么从一个元素创建一个列表
让我们想象一下,我有以下蜘蛛:
# -*- 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)
?这会是一个推荐的解决方案吗?或者我错了?
感谢
是,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
的处理器,它接收当前值的每个条目并应用每个定义为参数的方法。
你确定'comment = comment_it.extract()'是一个字符串吗? – eLRuLL
@eLRuLL是的。在add_value类型(注释)---> Out [2]:unicode附近设置一个断点。似乎是Unicode字符串 –