本文简单介绍一下 Scrapy 框架中的 Item Pipeline 的用法。
Item Pipeline 的调用发生在 Spider 产生 Item 之后。当 Spider 解析完 Response 之后,Item 就会传递到 Item Pipeline,被定义的 Item Pipeline 组件会顺次调用,完成一连串的处理过程,比如数据清洗、存储等。
Item Pipeline 的主要功能有如下 4 点。
- 清理 HTML 数据。
- 验证爬取数据,检查爬取字段。
- 查重并丢弃重复内容。
- 将爬取结果保存到数据库。
核心方法
我们可以自定义 Item Pipeline,只需要实现指定的方法,其中必须要实现的一个方法是:process_item(item, spider)
。
另外还有如下几个比较实用的方法。
open_spider(spider)
close_spider(spider)
from_crawler(cls, crawler)
下面我们详细介绍这几个方法的用法。
process_item(item, spider)
process_item()
是必须要实现的方法,被定义的 Item Pipeline 会默认调用这个方法对 Item 进行处理。比如,我们可以进行数据处理或者将数据写入到数据库等操作。它必须返回 Item 类型的值或者抛出一个 DropItem 异常。
process_item()
方法的参数有如下两个。
- item,是 Item 对象,即被处理的 Item。
- spider,是 Spider 对象,即生成该 Item 的 Spider。
process_item()
方法的返回类型归纳如下。
- 如果它返回的是 Item 对象,那么此 Item 会被低优先级的 Item Pipeline 的
process_item()
方法处理,直到所有的方法被调用完毕。 - 如果它抛出的是 DropItem 异常,那么此 Item 会被丢弃,不再进行处理。
open_spider(self, spider)
open_spider()
方法是在 Spider 开启的时候被自动调用的。在这里我们可以做一些初始化操作,如开启数据库连接等。其中,参数 spider 就是被开启的 Spider 对象。
close_spider(spider)
close_spider() 方法是在 Spider 关闭的时候自动调用的。在这里我们可以做一些收尾工作,如关闭数据库连接等。其中,参数 spider 就是被关闭的 Spider 对象。
from_crawler(cls, crawler)
from_crawler()
方法是一个类方法,用@classmethod
标识,是一种依赖注入的方式。它的参数是 crawler,通过 crawler 对象,我们可以拿到 Scrapy 的所有核心组件,如全局配置的每个信息,然后创建一个 Pipeline 实例。参数 cls 就是 Class,最后返回一个 Class 实例。
实例
MongoDB Pipeline
我们用一个 MongoPipeline 将信息保存到 MongoDB,在pipelines.py
里添加如下类的实现:
import pymongo
class MongoPipeline(object):
def __init__(self, mongo_uri, mongo_db):
self.mongo_uri = mongo_uri
self.mongo_db = mongo_db
def from_crawler(cls, crawler):
return cls(
mongo_uri=crawler.settings.get('MONGO_URI'),
mongo_db=crawler.settings.get('MONGO_DB')
)
def open_spider(self, spider):
self.client = pymongo.MongoClient(self.mongo_uri)
self.db = self.client[self.mongo_db]
def process_item(self, item, spider):
self.db[item.collection].insert(dict(item))
return item
def close_spider(self, spider):
self.client.close()
这里需要用到两个变量,MONGO_URI 和 MONGO_DB,即存储到 MongoDB 的链接地址和数据库名称。我们在 settings.py 里添加这两个变量,如下所示:
代码语言:javascript复制MONGO_URI = 'localhost'
MONGO_DB = 'images360'
样一个保存到 MongoDB 的 Pipeline 的就创建好了。这里最主要的方法是process_item()
方法,直接调用 Collection 对象的insert()
方法即可完成数据的插入,最后返回 Item 对象。