scrapy框架开发爬虫实战——Item Pipeline管道

Item Pipeline简介

在Scrapy中, ItemPipeline是处理数据的组件, 一个Item Pipeline就是一个包含特定接口的类, 通常只负责一种功能的数据处理, 在一个项目中可以同时启用多个Item Pipeline, 它们按指定次序级联起来, 形成一条数据处理流水线。


以下是Item Pipeline的几种典型应用:
● 清洗数据。
● 验证数据的有效性。
● 过滤掉重复的数据。
● 将数据存入数据库。

实现Item Pipiline

在创建一个Scrapy项目时, 会自动生成一个pipelines.py文件,它用来放置用户自定义的Item Pipeline。

scrapy框架开发爬虫实战——Item Pipeline管道

一个Item Pipeline不需要继承特定基类, 只需要实现某些特定方法, 例如process_item、 open_spider、close_spider。
一个Item Pipeline必须实现一个process_item(item,spider)方法, 该方法用来处理每一项由Spider爬取到的数据, 其中的两个参数:

  • Item 爬取到的一项数据(Item或字典)
  • Spider 爬取此项数据的Spider对象。

process_item方法是Item Pipeline的核心, 对该方法还需再做两点补充说明:

  • 如果process_item在处理某项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对象。

启用Item Pipeline

在Scrapy中, Item Pipeline是可选的组件, 想要启用某个(或某些) Item Pipeline, 需要在配置文件settings.py中进行配置:

ITEM_PIPELINES = {
'example.pipelines.PriceConverterPipeline': 300,
}

scrapy框架开发爬虫实战——Item Pipeline管道

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,
}

上一篇:scrapy框架开发爬虫实战——如何调试项目


下一篇:爬虫部署-3,爬虫管理平台,Crawlab、Gerapy、Scrapydweb,SpiderKeeper,scrapyd,基于上述平台,构思自己的爬虫管理平台