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迭代用法实例教程
Sep 08 Python
Python多线程下载文件的方法
Jul 10 Python
Python实现翻转数组功能示例
Jan 12 Python
对python mayavi三维绘图的实现详解
Jan 08 Python
python gensim使用word2vec词向量处理中文语料的方法
Jul 05 Python
python通过TimedRotatingFileHandler按时间切割日志
Jul 17 Python
python sqlite的Row对象操作示例
Sep 11 Python
PyCharm更改字体和界面样式的方法步骤
Sep 27 Python
Python中类似于jquery的pyquery库用法分析
Dec 02 Python
django Model层常用验证器及自定义验证器详解
Jul 15 Python
Python经纬度坐标转换为距离及角度的实现
Nov 01 Python
python爬虫中采集中遇到的问题整理
Nov 27 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入门学习知识点六 PHP文件的读写操作代码
2011/07/14 PHP
PHP 文件系统详解
2012/09/13 PHP
解析php session_set_save_handler 函数的用法(mysql)
2013/06/29 PHP
解析VS2010利用VS.PHP插件调试PHP的方法
2013/07/19 PHP
使用php判断服务器是否支持Gzip压缩功能
2013/09/24 PHP
PHP 正则表达式常用函数
2014/08/17 PHP
PHP上传图片到数据库并显示的实例代码
2019/12/20 PHP
PHP实现基本留言板功能原理与步骤详解
2020/03/26 PHP
张孝祥JavaScript学习阶段性总结(2)--(X)HTML学习
2007/02/03 Javascript
javascript 循环读取JSON数据的代码
2010/07/17 Javascript
jquery 简短几句代码实现给元素动态添加及获取提示信息
2011/09/01 Javascript
JavaScript高级程序设计 阅读笔记(七) ECMAScript中的语句
2012/02/27 Javascript
javascript中有趣的反柯里化深入分析
2012/12/05 Javascript
javascript创建和存储cookie示例
2014/01/07 Javascript
Nodejs中调用系统命令、Shell脚本和Python脚本的方法和实例
2015/01/01 NodeJs
不使用script导入js文件的几种方法
2016/10/27 Javascript
xmlplus组件设计系列之图标(ICON)(1)
2017/05/05 Javascript
js 获取元素的具体样式信息getcss(实例讲解)
2017/07/05 Javascript
vue devtools的安装与使用教程
2018/08/08 Javascript
jquery+php后台实现省市区联动功能示例
2019/05/23 jQuery
JavaScript面向对象核心知识与概念归纳整理
2020/05/09 Javascript
原生JavaScript写出Tabs标签页的实例代码
2020/07/20 Javascript
js前端对于大量数据的展示方式及处理方法
2020/12/02 Javascript
Tensorflow实现神经网络拟合线性回归
2019/07/19 Python
Django ORM多对多查询方法(自定义第三张表&ManyToManyField)
2019/08/09 Python
互斥锁解决 Python 中多线程共享全局变量的问题(推荐)
2020/09/28 Python
html5读取本地文件示例代码
2014/04/22 HTML / CSS
海蓝之谜(LA MER)澳大利亚官方商城:全球高端奢华护肤品牌
2017/10/27 全球购物
医药营销专业个人自荐信
2013/09/29 职场文书
2015年保险公司内勤工作总结
2015/05/23 职场文书
美德少年主要事迹材料
2015/11/04 职场文书
幼师自荐信范文(2016推荐篇)
2016/01/28 职场文书
SQLServer2019 数据库的基本使用之图形化界面操作的实现
2021/04/08 SQL Server
uniapp开发小程序的经验总结
2021/04/08 Javascript
Python3 如何开启自带http服务
2021/05/18 Python
Python爬虫框架之Scrapy中Spider的用法
2021/06/28 Python