
点击上方蓝字,获得更多精彩内容
有时,我们想把爬取到的数据存入某种数据库中,可以实现 Item Pipeline 完成此类任务。下面实现一个能将数据存入 MongoDB 数据库的 Item Pipeline,创建 demo5 项目(与demo4相同),实现 MongoDBPipeline类,代码如下:
from scrapy.item import Itemimport pymongoclass MongoDBPipeline(object):DB_URI = 'mongodb://localhost:27017/'DB_NAME = 'scrapy_data'def open_spider(self, spider):self.client = pymongo.MongoClient(self.DB_URI)self.db = self.client[self.DB_NAME]def close_spider(self, spider):self.client.close()def process_item(self, item, spider):collection = self.db[spider.name]post = dict(item) if isinstance(item, Item) else itemcollection.insert_one(post)return item
对上述代码解释如下:
在类属性中定义两个常量:
① DB_URI:数据库的 URI 地址。
② DB_NAME:数据库的名字。
在 Spider 整个爬取过程中,数据库的连接和关闭操作只需要进行一次,应该在开始处理数据之前连接数据库,并在处理完所有数据之后关闭数据库,因此实现以下两个方法(在 Spider 打开和关闭时被调用):
① open_spider(self, spider)
② close_spider(self, spider)
分别在 open_spider 和 close_spider 方法中实现数据库的连接与关闭。
在 process_item 中实现 MongoDB 数据库的写入操作,使用 self.db 和 spider.name 获取一个集合(collection),然后将数据插入该集合,集合对象的 insert_one 方法需要传入一个字典对象(不能传入 Item 对象),因此在调用前先对 item 的类型进行判断,如果 item 是 Item 对象,就将其转换为字典。
下一步,我们在 Robo 3T 中创建一个名为“scrapy_data”的数据库:

接下来测试 MongoDBPipeline ,在配置文件 settings.py 中启用 MongoDBPipeline:
ITEM_PIPELINES = {'demo5.pipelines.PriceConverterPipeline': 300,'demo5.pipelines.DuplicatesPipeline': 350,'demo5.pipelines.MongoDBPipeline': 400,}
执行以下命令运行爬虫,并查看数据库中的结果:
scrapy crawl books


from scrapy.item import Itemimport pymongoclass MongoDBPipeline(object):# 直接定义方式# DB_URI = 'mongodb://localhost:27017/'# DB_NAME = 'scrapy_data'# 配置文件方式# 类方法(不需要实例化类就可以被类本身调用)@classmethoddef from_crawler(cls, crawler):cls.DB_URI = crawler.settings.get('MONGO_DB_URI', 'mongodb://localhost:27017/')cls.DB_NAME = crawler.settings.get('MONGO_DB_NAME', 'scrapy_data2')return cls()def open_spider(self, spider):self.client = pymongo.MongoClient(self.DB_URI)self.db = self.client[self.DB_NAME]def close_spider(self, spider):self.client.close()def process_item(self, item, spider):collection = self.db[spider.name]post = dict(item) if isinstance(item, Item) else itemcollection.insert_one(post)return item

增加类方法 from_crawler(cls, crawler),替代在类属性中定义 DB_URI 和 DB_NAME 。
如果一个 Item Pipeline 定义了 from_crawler 方法,Scrapy 就会调用该方法来创建 Item Pipeline 对象。该方法有两个参数:
① cls:Item Pipeline 类的对象(这里为 MongoDBPipeline 类对象)。
② crawler:Crawler 是 Scrapy 中的一个核心对象,可以通过 crawler 的 settings 属性访问配置文件。
在 from_crawler 方法中,读取配置文件中的 MONGO_DB_URI 和 MONGO_DB_NAME (不存在使用默认值),赋给 cls 的属性,即 MongoDBPipeline 类属性。
classmethod 修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等。
其他代码并没有任何改变,因为这里只是改变了设置 MongoDBPipeline 类属性的方式。
MONGO_DB_URI = 'mongodb://localhost:27017/'MONGO_DB_NAME = 'scrapy_data2'

重新执行以下命令运行爬虫,并查看数据库中的结果:
scrapy crawl books

内容参考:
Scrapy官方文档、《精通Scrapy网络爬虫》、百度。

END

这里“阅读原文”,查看github中的代码




