定时将redis数据存入mysql_NO.14 Scrapy 将数据存入 MongoDB

有时,我们想把爬取到的数据存入某种数据库中,可以实现 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 item        collection.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

在上述实现中,数据库的 URI 地址和数据库的名字硬编码在代码中,如果希望通过配置文件设置它们,只需要稍作改动,代码如下:

from scrapy.item import Itemimport pymongoclass MongoDBPipeline(object):    # 直接定义方式    # DB_URI = 'mongodb://localhost:27017/'    # DB_NAME = 'scrapy_data'    # 配置文件方式    # 类方法(不需要实例化类就可以被类本身调用)    @classmethod    def 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 item        collection.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 类属性的方式。

现在,我们可以在配置文件 settings.py 中对所要使用的数据库进行设置:

MONGO_DB_URI = 'mongodb://localhost:27017/'MONGO_DB_NAME = 'scrapy_data2'

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

scrapy crawl books

查看scrapy_data2数据库,数据已经正常存入。

本篇文章相关代码可在 github 获得:

https://github.com/05dt/scrapy

内容参考:

Scrapy官方文档、《精通Scrapy网络爬虫》、百度。

END

Original: https://blog.csdn.net/weixin_32347459/article/details/112382014
Author: 职业规划师Will
Title: 定时将redis数据存入mysql_NO.14 Scrapy 将数据存入 MongoDB

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/792203/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球