美文网首页
爬虫框架scrapy篇四——数据入库(mongodb,mysql

爬虫框架scrapy篇四——数据入库(mongodb,mysql

作者: 一只酸柠檬精 | 来源:发表于2021-01-29 09:27 被阅读0次

    这篇将爬虫框架scrapy篇三中的第四步展开来讲,主要讲数据存入mongodb和mysql的不同方法
    目录
    1、数据存入mongodb,连接数据库的两种方法
    1.1 连接方式一:直接初始化,传入相应的值
    1.2 连接方式二: 在setting.py配置文件中设置参数,调用setting.py文件中的参数值
    2、数据存入mysql,插入数据的两种方式
    2.1 插入方式一:同步插入数据
    2.2 插入方式二:异步插入数据(连接池)

    1、数据存入mongodb,连接数据库的两种方法

    链接MongoDB数据库有两种方法:

    1、不需要在setting.py配置相应的参数,直接初始化连接参数

    2、需要在setting.py配置相应的参数

    1.1 连接方式一:直接初始化,传入相应的值

    pipelines

    from pymongo import MongoClient
    from scrapy.exceptions import DropItem
    
    
    # 存入mongodb数据库,初始化的时候,直接传入相应的值
    class Movie80SPipeline:
        def __init__(self, databaseIp='127.0.0.1', databasePort=27017,
                     mongodbName='scrapy_movie80'):
            client = MongoClient(databaseIp, databasePort)
            self.db = client[mongodbName]
            # self.db.authenticate(user, password)
            self.title = set()  # 定义数据去重的集合
    
        def process_item(self, item, spider):
            title = item['moviename']  # 取出要进行判断数据是否重复的字段
            if title in self.title:  # 如果存在集合中则直接删除该项,
                raise DropItem('{}已存在'.format(title))
            else:
                self.title.add(title)  # 如果数据不重复,则加入集合
    
                postItem = dict(item)  # 把item转化成字典形式
                self.db.scrapy.insert(postItem)  # 向数据库插入一条记录
            # 优先级高的管道类这里必须返回item,否则在优先级低的管道类中接收不到item会报错
            return item
    

    1.2 连接方式二: 在setting.py配置文件中设置参数,调用setting.py文件中的参数值

    settings

    # 在settings中加上以下参数
    MONGO_HOST = "127.0.0.1"  # 主机IP
    MONGO_PORT = 27017  # 端口号
    MONGO_DB = "scrapy_movie80"  # 库名
    MONGO_COLL = "scrapy"  # collection名,相当于表名
    MONGO_USER = ""  # 用户名
    MONGO_PSW = ""  # 用户密码
    

    pipelines

    import pymongo
    from scrapy.utils.project import get_project_settings
    settings = get_project_settings()
    # 存入mongodb数据库,在setting.py配置文件中设置参数,调用setting.py文件中的参数值
    class Movie80SPipeline:
        def __init__(self):
            # 链接数据库
            client = pymongo.MongoClient(host=settings['MONGO_HOST'], port=settings['MONGO_PORT'])
            self.db = client[settings['MONGO_DB']]  # 获得数据库的句柄
            self.coll = self.db[settings['MONGO_COLL']]  # 获得collection的句柄
            # 数据库登录需要帐号密码的话
            # self.db.authenticate(settings['MONGO_USER'], settings['MONGO_PSW'])
            self.title = set()  # 定义数据去重的集合
    
        def process_item(self, item, spider):
            title = item['moviename']  # 取出要进行判断数据是否重复的字段
            if title in self.title:  # 如果存在集合中则直接删除该项,
                raise DropItem('{}已存在'.format(title))
            else:
                self.title.add(title)  # 如果数据不重复,则加入集合
    
                postItem = dict(item)  # 把item转化成字典形式
                self.db.scrapy.insert(postItem)  # 向数据库插入一条记录
            # 优先级高的管道类这里必须返回item,否则在优先级低的管道类中接收不到item会报错
            return item
    

    2、数据存入mysql,插入数据的两种方式

    链接mysql的方式和mongodb一样也是两种,大同小异,不做细讲。
    主要讲讲mysql的存入方式:

    同步插入(一个连接,适用数据量小的情况)
    同步插入数据就是一条数据一条数据的插入数据库,当数据量特别大的时候,就需要排队等待。所以,在数据量大的情况下,同步插入就会显得速度很慢。

    异步插入(连接池,多个连接,适用数据量大的情况)。
    异步插入是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。在数据量大的时候,多个连接对数据进行操作,大大提升了插入数据的效率。

    2.1 插入方式一:同步插入数据

    pipelines

    import pymysql
    # 存入mysql数据库
    class Movie80SPipeline:
        """
        同步操作
        """
    
        def __init__(self):
            # 建立连接
            self.conn = pymysql.connect(host='127.0.0.1', port=3306, db="scrapy_movie80", user='root', passwd='123456', charset='utf8')
            # 创建游标
            self.cursor = self.conn.cursor()
            # 定义数据去重的集合
            self.title = set()
    
        def process_item(self, item, spider):
            title = item['moviename']  # 取出要进行判断数据是否重复的字段
            if title in self.title:  # 如果存在集合中则直接删除该项,
                raise DropItem('{}已存在'.format(title))
            else:
                self.title.add(title)  # 如果数据不重复,则加入集合
    
                # sql语句
                insert_sql = """
                insert into scrapy(moviename,movielink,moviedirector,movieregion,movieReleasedate) VALUES(%s,%s,%s,%s,%s)
                """
    
                try:
                    # 执行插入数据到数据库操作
                    self.cursor.execute(insert_sql,
                                        (item['moviename'], item['movielink'], item['moviedirector'], item['movieregion'],
                                         item['movieReleasedate']))
                    # 提交,不进行提交无法保存到数据库
                    self.conn.commit()
                except:
                    # 保存数据失败,回滚操作
                    self.conn.rollback()
            # 优先级高的管道类这里必须返回item,否则在优先级低的管道类中接收不到item会报错
            return item
    
        def close_spider(self, spider):
            # 关闭游标和连接
            self.cursor.close()
            self.conn.close()
    

    2.2 插入方式二:异步插入数据(连接池)

    settings

    # Mysql数据库的配置信息
    MYSQL_HOST = '127.0.0.1'  # 主机IP
    MYSQL_PORT = 3306  # 数据库端口
    MYSQL_DBNAME = 'scrapy_movie80'  # 数据库名字
    MYSQL_USER = 'root'  # 数据库账号
    MYSQL_PASSWD = 'xxx'  # 数据库密码
    

    pipelines

    import pymysql
    from twisted.enterprise import adbapi
    
    
    # # 存入mysql数据库
    class Movie80SPipeline1(object):
       #     """
       #     异步操作,连接池
       #     """
       def __init__(self, dbpool):
           self.dbpool = dbpool
           # 定义数据去重的集合
           self.title = set()
    
       @classmethod
       def from_settings(cls, settings):  # 函数名固定,会被scrapy调用,直接可用settings的值
           """
           数据库建立连接
           :param settings: 配置参数
           :return: 实例化参数
           """
           adbparams = dict(
               host=settings['MYSQL_HOST'],
               db=settings['MYSQL_DBNAME'],
               user=settings['MYSQL_USER'],
               password=settings['MYSQL_PASSWD'],
               cursorclass=pymysql.cursors.DictCursor  # 指定cursor类型
           )
           # 连接数据池ConnectionPool,使用pymysql连接
           dbpool = adbapi.ConnectionPool('pymysql', **adbparams)
           # 返回实例化参数
           return cls(dbpool)
    
       def process_item(self, item, spider):
           """
           使用twisted将MySQL插入变成异步执行。通过连接池执行具体的sql操作,返回一个对象
           """
           query = self.dbpool.runInteraction(self.do_insert, item)  # 指定操作方法和操作数据
           # 添加异常处理
           query.addCallback(self.handle_error)  # 处理异常
    
           # 优先级最低的管道类的return会在控制台输出原item数据,可以选择不写
           return item
    
       def do_insert(self, cursor, item):
           # 对数据库进行插入操作,并不需要commit,twisted会自动commit
           insert_sql = """
           insert into scrapy(moviename,movielink,moviedirector,movieregion,movieReleasedate) VALUES(%s,%s,%s,%s,%s)
           """
           cursor.execute(insert_sql, (item['moviename'], item['movielink'],
                                      item['moviedirector'], item['movieregion'], item['movieReleasedate']))
    
       def handle_error(self, failure):
           if failure:
               # 打印错误信息
               print(failure)
    

    传送门
    爬虫框架scrapy篇一——scrapy的架构
    https://www.jianshu.com/p/39b326f9cad6
    爬虫框架scrapy篇二——创建一个scrapy项目
    https://www.jianshu.com/p/00d99a9628b0
    爬虫框架scrapy篇三——数据的处理与持久化以及遇到的一些问题
    https://www.jianshu.com/p/8824623b551c
    爬虫框架scrapy篇五——其他操作:post翻页请求
    https://www.jianshu.com/p/bca689b4ebbd
    参考:
    MySql数据库连接池
    scrapy保存到mysql数据库
    Python:No module named 'scrapy.conf'

    相关文章

      网友评论

          本文标题:爬虫框架scrapy篇四——数据入库(mongodb,mysql

          本文链接:https://www.haomeiwen.com/subject/cetqtltx.html