scrapy数据存储在mysql数据库的两种方式(同步和异步)


Posted in Python onFebruary 18, 2020

方法一:同步操作

1.pipelines.py文件(处理数据的python文件)

import pymysql
 
class LvyouPipeline(object):
  def __init__(self):
    # connection database
    self.connect = pymysql.connect(host='XXX', user='root', passwd='XXX', db='scrapy_test') # 后面三个依次是数据库连接名、数据库密码、数据库名称
    # get cursor
    self.cursor = self.connect.cursor()
    print("连接数据库成功")
 
  def process_item(self, item, spider):
    # sql语句
    insert_sql = """
    insert into lvyou(name1, address, grade, score, price) VALUES (%s,%s,%s,%s,%s)
    """
    # 执行插入数据到数据库操作
    self.cursor.execute(insert_sql, (item['Name'], item['Address'], item['Grade'], item['Score'],
                     item['Price']))
    # 提交,不进行提交无法保存到数据库
    self.connect.commit()
 
  def close_spider(self, spider):
    # 关闭游标和连接
    self.cursor.close()
    self.connect.close()

2.配置文件中

scrapy数据存储在mysql数据库的两种方式(同步和异步)

方式二 异步储存

pipelines.py文件:

通过twisted实现数据库异步插入,twisted模块提供了 twisted.enterprise.adbapi

1. 导入adbapi

2. 生成数据库连接池

3. 执行数据数据库插入操作

4. 打印错误信息,并排错 

import pymysql
from twisted.enterprise import adbapi
# 异步更新操作
class LvyouPipeline(object):
  def __init__(self, dbpool):
    self.dbpool = dbpool
 
  @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_PASSWORD'],
      cursorclass=pymysql.cursors.DictCursor  # 指定cursor类型
    )
 
    # 连接数据池ConnectionPool,使用pymysql或者Mysqldb连接
    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) # 处理异常
 
  def do_insert(self, cursor, item):
    # 对数据库进行插入操作,并不需要commit,twisted会自动commit
    insert_sql = """
    insert into lvyou(name1, address, grade, score, price) VALUES (%s,%s,%s,%s,%s)
    """
    self.cursor.execute(insert_sql, (item['Name'], item['Address'], item['Grade'], item['Score'],
                         item['Price']))
 
  def handle_error(self, failure):
    if failure:
      # 打印错误信息
      print(failure)

注意:

1、python 3.x 不再支持MySQLdb,它在py3的替代品是: import pymysql。

2、报错pymysql.err.ProgrammingError: (1064, ……

原因:当item['quotes']里面含有引号时,可能会报上述错误

解决办法:使用pymysql.escape_string()方法

例如:

sql = """INSERT INTO video_info(video_id, title) VALUES("%s","%s")""" % (video_info["id"],pymysql.escape_string(video_info["title"]))

3、存在中文的时候,连接需要添加charset='utf8',否则中文显示乱码。

4、每执行一次爬虫,就会将数据追加到数据库中,如果多次的测试爬虫,就会导致相同的数据不断累积,怎么实现增量爬取?

  • scrapy-deltafetch
  • scrapy-crawl-once(与1不同的是存储的数据库不同)
  • scrapy-redis
  • scrapy-redis-bloomfilter(3的增强版,存储更多的url,查询更快)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现比较两个列表(list)范围
Jun 12 Python
Python 元类实例解析
Apr 04 Python
python3+PyQt5+Qt Designer实现扩展对话框
Apr 20 Python
python爬取微信公众号文章
Aug 31 Python
使用Python如何测试InnoDB与MyISAM的读写性能
Sep 18 Python
详解Python字典小结
Oct 20 Python
利用python和ffmpeg 批量将其他图片转换为.yuv格式的方法
Jan 08 Python
pyqt5实现登录界面的模板
May 30 Python
Tensorflow累加的实现案例
Feb 05 Python
在python下实现word2vec词向量训练与加载实例
Jun 09 Python
浅析python 字典嵌套
Sep 29 Python
python 怎样进行内存管理
Nov 10 Python
通过python连接Linux命令行代码实例
Feb 18 #Python
Python日志syslog使用原理详解
Feb 18 #Python
Pytorch中.new()的作用详解
Feb 18 #Python
Pytorch maxpool的ceil_mode用法
Feb 18 #Python
浅谈pytorch池化maxpool2D注意事项
Feb 18 #Python
Python3的socket使用方法详解
Feb 18 #Python
Python批量启动多线程代码实例
Feb 18 #Python
You might like
PHP中操作ini配置文件的方法
2013/04/25 PHP
PHP实现简单数字分页效果
2015/07/26 PHP
thinkPHP微信分享接口JSSDK用法实例
2017/07/07 PHP
JavaScript 面向对象编程(2) 定义类
2010/05/18 Javascript
js比较和逻辑运算符的介绍
2013/03/10 Javascript
JS获取select-option-text_value的方法
2013/12/26 Javascript
JavaScript Promise启示录
2014/08/12 Javascript
javascript定义变量时带var与不带var的区别分析
2015/01/12 Javascript
JavaScript判断用户是否对表单进行了修改的方法
2015/03/18 Javascript
JS模拟的Map类实现方法
2016/06/17 Javascript
js方法数据验证的简单实例
2016/09/17 Javascript
微信小程序 限制1M的瘦身技巧与方法详解
2017/01/06 Javascript
微信小程序 action-sheet 反馈上拉菜单简单实例
2017/05/11 Javascript
详解如何使用Node.js编写命令工具——以vue-cli为例
2017/06/29 Javascript
Angular.js中angular-ui-router的简单实践
2017/07/18 Javascript
vue 挂载路由到头部导航的方法
2017/11/13 Javascript
vue-cli与webpack处理静态资源的方法及webpack打包的坑
2018/05/15 Javascript
微信小程序自定义组件实现tabs选项卡功能
2018/07/14 Javascript
JavaScript执行环境及作用域链实例分析
2018/08/01 Javascript
微信小程序保存多张图片的实现方法
2019/03/05 Javascript
[01:31](回顾)杀出重围,决战TI之巅
2014/07/01 DOTA
[43:35]TI4 循环赛第二日Liquid vs Fnatic
2014/07/11 DOTA
python字符串连接的N种方式总结
2014/09/17 Python
深入理解Python中变量赋值的问题
2017/01/12 Python
python3处理含有中文的url方法
2018/05/10 Python
和孩子一起学习python之变量命名规则
2018/05/27 Python
Python hmac模块使用实例解析
2019/12/24 Python
keras自定义回调函数查看训练的loss和accuracy方式
2020/05/23 Python
Python爬虫之Spider类用法简单介绍
2020/08/04 Python
电子商务专业个人的自我评价分享
2013/10/29 职场文书
博士生专家推荐信
2014/09/26 职场文书
继续教育个人总结
2015/03/03 职场文书
施工现场安全管理制度
2015/08/05 职场文书
工作感想范文
2015/08/07 职场文书
《好妈妈胜过好老师》:每个孩子的优秀都是有源头的
2020/01/03 职场文书
golang 如何通过反射创建新对象
2021/04/28 Golang