为什么在Scrapy中抓取文本是蜘蛛中的字符串,但是作为管道中的列表?

时间:2017-11-04 09:20:14

标签: scrapy scrapy-spider scrapy-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]。例如。项[&#39; price_euro&#39;] [0]

我可以禁用此功能吗?我应该这样做吗? 这背后的逻辑是什么?

谢谢

我如何添加price_euro

l = ItemLoader(item=MyItem(), response=response)
l.add_value('price_euro', price_euro)      
yield l.load_item()   

1 个答案:

答案 0 :(得分:3)

ItemLoader允许为同一字段多次调用add_value()(以及add_css()add_xpath() 。当您要查找的信息可以在HTML源的多个位置找到,或者HTML布局在请求之间不同时,这非常有用。为了适应这种情况,项加载器将所有字段值存储在列表中。

当您期望该字段只有一个值时(就您的价格信息而言),您可以通过指定output processor告诉项目加载器在调用load_item()时如何转换列表。执行此操作的规范方法是通过继承ItemLoader类:

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()  

如果要为项目的所有字段启用此“获取第一个列表元素”行为,您还可以为项目加载器声明默认输出处理器:

class MyItemLoader(ItemLoader):
    default_item_class = MyItem
    default_output_processor = TakeFirst()

Scrapy文档有list of built-in processors