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

这篇将爬虫框架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))