在Scrapy中,Item Pipeline 是处理数据的组件,通常只负责一种功能的数据处理,在一个项目中可以同时启用多个Item Pipeline,它们按指定次序级联起来,形成一条数据处理流水线.
Item Pipeline的几种典型应用:
- 清洗数据
- 验证数据的有效性
- 过滤掉重复的数据
- 将数据存入数据库
1. Item Pipeline
在之前的example项目中,我们爬取到的书籍价格是以英镑为单位的,如果我们希望爬取到的书价是人民币价格呢?
就需要根据汇率算出人民币价格,此时可以实现一个价格转换的Item Pipeline来完成这个工作
1. 实现Item Pipeline
在创建项目时,会自动生成一个pipelines.py文件,用来放置用户自定义的Item Pipeline
class PriceConverterPipeline(object):
# 英镑兑换人民币汇率
exchange_rate = 8.5309
def process_item(self, item, spider):
# 提取item的price字段
# 去掉前面的英镑符号,转换为float类型,乘以汇率
price = float(item['price'][1:]) * self.exchange_rate
# 保留2位小数,赋值回item的price字段
item['price'] = '¥%.2f' % price
return item
一个Item Pipeline 不需要继承特定基类,只需要实现某些特定的方法,例如,process_item , open_spider , close_spider
必须实现一个 process_item(item,spider)方法,该方法用来处理每一项由Spider爬取到的数据,其中的两个参数:
item 爬取到的一项数据 spider 爬取此项数据的Spider对象
可以看出, process_item 方法是Item Pipeline的核心
- 如果process_item在处理某项item时返回了一项数据,返回的数据会传递给下一级 Item Pipeline(如果有)继续处理
- 如果process_item 在处理某项item时抛出(raise)一个DropItem异常(scrapy.exceptions.DropItem),该项item便会抛弃,不会传递给后面的Item Pipeline继续处理,也不会导出到文件.通常,我们在检测到无效数据或想要过滤数据时,抛出DropItem异常
除了必须实现的process_item方法外,还有3个比较常用的方法
open_spider(self,spider)
Spider打开时(处理数据前)回调该方法,通常该方法用于在处理数据之前完成某些初始化工作,如连接数据库
close_spider(self,spider)
Spider关闭时(处理数据后)回调该方法,通常该方法用于在处理完成所有数据之后完成某些清理工作,如关闭数据库
from_crawler(cls,crawler)
创建Item Pipeline对象时回调该类方法.通常,在该方法中通过crawler.settings读取配置,根据配置创建ItemPipeline对象
2. 启用Item Pipeline
Item Pipeline是可选的组件,想要启动某Item Pipeline,需要在配置文件settings.py 中进行配置
ITEM_PIPELINES = {
'example.pipelines.PriceConverterPipeline': 300,
}
ITEM_PIPELINES 是一个字典,每一项的键是每一个Item Pipeline类的导入路径,值是0-1000的数字,同时启用多个Item Pipeline时,Scrapy根据这些数值决定各个Item Pipeline 处理数据的先后次序,数值小的在前
重新运行爬虫,观察结果
scrapy crawl books -o books2.csv
2. 更多栗子
1. 过滤重复数据
class DuplicatesPipeline(object):
def __init__(self):
self.book_set = set()
def process_item(self, item, spider):
name = item['name']
if name in self.book_set:
raise DropItem("Duplicate book found:%s" % item)
self.book_set.add(name)
return item
修改 settings.py,重新运行,发现比之前的数据少了一条,对比发现,确实过滤掉重复数据了
2. 将数据存入MongoDB
未完待续