为什么在 Scrapy 中抓取的文本在蜘蛛中是字符串,而在管道中是列表?
Why in Scrapy scraped text is as string in spider, but as list in pipeline?
有人可以给我解释一下吗?
在我的蜘蛛中,我有使用 XPath 提取数据的代码。
price_euro = add.xpath('.//strong[@class="price price--eur"]/text()').extract_first()
print 'price_euro', price_euro, type(price_euro)
我得到的是:
price_euro 25.500 <type 'unicode'>
我明白这一点,我把它作为一个字符串(Unicode),因为我使用了 .extract_first() ,这就是我想要的。
但在我的管道中,
print "item['price_euro']", item['price_euro'], type(item['price_euro'])
我有一个列表
item['price_euro'] [u'25.500 '] <type 'list'>
这对我来说不是什么大问题,但很烦人,因为每次我想访问它时都需要在它的末尾添加 [0]。例如。项目['price_euro'][0]
我可以禁用它吗?
这背后的逻辑是什么?
谢谢
我如何添加price_euro
l = ItemLoader(item=MyItem(), response=response)
l.add_value('price_euro', price_euro)
yield l.load_item()
ItemLoader
允许调用 add_value()
(以及 add_css()
和 add_xpath()
)同一字段多次 .当您要查找的信息可以在 HTML 源的多个位置找到时,或者当 HTML 布局因请求而异时,这将很有帮助。为了适应这一点,项目加载器将所有字段值存储在列表中。
当您期望该字段只有一个值时(对于您的价格信息),您可以通过指定 output processor 告诉项目加载器如何在调用 load_item()
时转换列表。做到这一点的规范方法是通过 subclassing ItemLoader
class:
from scrapy.loader import ItemLoader
from scrapy.loader.processors import TakeFirst
class MyItemLoader(ItemLoader):
default_item_class = MyItem
price_euro_out = TakeFirst()
然后您可以像以前一样填充此项目加载器,还有一个好处是您不再需要告诉项目加载器要使用哪种项目类型:
l = MyItemLoader(response=response)
l.add_value('price_euro', price_euro)
yield l.load_item()
对于您发布的示例代码,您甚至可以避免通过 add_xpath()
方法手动提取并将 add
作为 selector
关键字参数传递给项目加载器:
l = MyItemLoader(selector=add)
l.add_xpath('price_euro', './/strong[@class="price price--eur"]/text()')
yield l.load_item()
如果您想为项目的 所有 字段启用此 "take the first list element" 行为,您还可以为项目加载器声明默认输出处理器:
class MyItemLoader(ItemLoader):
default_item_class = MyItem
default_output_processor = TakeFirst()
Scrapy 文档有 list of built-in processors.
有人可以给我解释一下吗?
在我的蜘蛛中,我有使用 XPath 提取数据的代码。
price_euro = add.xpath('.//strong[@class="price price--eur"]/text()').extract_first()
print 'price_euro', price_euro, type(price_euro)
我得到的是:
price_euro 25.500 <type 'unicode'>
我明白这一点,我把它作为一个字符串(Unicode),因为我使用了 .extract_first() ,这就是我想要的。
但在我的管道中,
print "item['price_euro']", item['price_euro'], type(item['price_euro'])
我有一个列表
item['price_euro'] [u'25.500 '] <type 'list'>
这对我来说不是什么大问题,但很烦人,因为每次我想访问它时都需要在它的末尾添加 [0]。例如。项目['price_euro'][0]
我可以禁用它吗?
这背后的逻辑是什么?
谢谢
我如何添加price_euro
l = ItemLoader(item=MyItem(), response=response)
l.add_value('price_euro', price_euro)
yield l.load_item()
ItemLoader
允许调用 add_value()
(以及 add_css()
和 add_xpath()
)同一字段多次 .当您要查找的信息可以在 HTML 源的多个位置找到时,或者当 HTML 布局因请求而异时,这将很有帮助。为了适应这一点,项目加载器将所有字段值存储在列表中。
当您期望该字段只有一个值时(对于您的价格信息),您可以通过指定 output processor 告诉项目加载器如何在调用 load_item()
时转换列表。做到这一点的规范方法是通过 subclassing ItemLoader
class:
from scrapy.loader import ItemLoader
from scrapy.loader.processors import TakeFirst
class MyItemLoader(ItemLoader):
default_item_class = MyItem
price_euro_out = TakeFirst()
然后您可以像以前一样填充此项目加载器,还有一个好处是您不再需要告诉项目加载器要使用哪种项目类型:
l = MyItemLoader(response=response)
l.add_value('price_euro', price_euro)
yield l.load_item()
对于您发布的示例代码,您甚至可以避免通过 add_xpath()
方法手动提取并将 add
作为 selector
关键字参数传递给项目加载器:
l = MyItemLoader(selector=add)
l.add_xpath('price_euro', './/strong[@class="price price--eur"]/text()')
yield l.load_item()
如果您想为项目的 所有 字段启用此 "take the first list element" 行为,您还可以为项目加载器声明默认输出处理器:
class MyItemLoader(ItemLoader):
default_item_class = MyItem
default_output_processor = TakeFirst()
Scrapy 文档有 list of built-in processors.