在Scrapy中, ItemPipeline是处理数据的组件, 一个Item Pipeline就是一个包含特定接口的类, 通常只负责一种功能的数据处理, 在一个项目中可以同时启用多个Item Pipeline, 它们按指定次序级联起来, 形成一条数据处理流水线。
以下是Item Pipeline的几种典型应用:
● 清洗数据。
● 验证数据的有效性。
● 过滤掉重复的数据。
● 将数据存入数据库。
在创建一个Scrapy项目时, 会自动生成一个pipelines.py文件,它用来放置用户自定义的Item Pipeline。
一个Item Pipeline不需要继承特定基类, 只需要实现某些特定方法, 例如process_item、 open_spider、close_spider。
一个Item Pipeline必须实现一个process_item(item,spider)方法, 该方法用来处理每一项由Spider爬取到的数据, 其中的两个参数:
process_item方法是Item Pipeline的核心, 对该方法还需再做两点补充说明:
除了必须实现的process_item方法外, 还有3个比较常用的方法, 可根据需求选择实现:
在Scrapy中, Item Pipeline是可选的组件, 想要启用某个(或某些) Item Pipeline, 需要在配置文件settings.py中进行配置:
ITEM_PIPELINES = {
'example.pipelines.PriceConverterPipeline': 300,
}
ITEM_PIPELINES是一个字典, 我们把想要启用的ItemPipeline添加到这个字典中, 其中每一项的键是每一个ItemPipeline类的导入路径, 值是一个0~1000的数字, 同时启用多个Item Pipeline时, Scrapy根据这些数值决定各Item Pipeline处理数据的先后次序, 数值小的在前。
在pipelines.py中创建 类PriceConverterPipeline,然后编辑process_item()函数。
from scrapy.exceptions import DropItem
from scrapy.item import Item
#处理数据
class PriceConverterPipeline(object):
#英镑兑换人民币汇率
exchange_rate=8.5309
def process_item(self,item,spider):
#提取item的price字段
#去掉前面的英镑符号,转换为float类型,乘以汇率
price =float(item['price'][1:])*self.exchange_rate
#保留两位小数,赋值回item的price字段
item['price']='Y%.2f'%price
return item
再编辑settings.py文件,添加ITEM_PIPELINE
# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'example.pipelines.PriceConverterPipeline': 300,
}
在pipelines.py中创建 类DuplicatesPipeline,然后编辑process_item()函数。
from scrapy.exceptions import DropItem
from scrapy.item import Item
#去重复数据
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文件,添加ITEM_PIPELINE
# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'example.pipelines.PriceConverterPipeline': 300,
'example.pipelines.DuplicatesPipeline': 350,
}