python异步存储数据详解


Posted in Python onMarch 19, 2019

在Python中,数据存储方式分为同步存储和异步存储。同步写入速度比较慢,而爬虫速度比较快,有可能导致数据保存不完整,一部分数据没有入库。而异步可以将爬虫和写入数据库操作分开执行,互不影响,所以写入速度比较快,能够保证数据的完整性。

异步存储数据库大致看分为以下步骤:

1. 在settings中配置Mysql链接需要的参数(主机地址、用户账号、密码、需要操作的表名、编码格式等)
2. 自定义Pipeline,实现from_settings函数
3. from twisted.enterprise import adbapi 引入连接池模块
4. from pymysql import cursors 引入游标模块
5. 在from_settings中,准备链接数据库参数,创建db_pool连接池,创建返回当前类的对象,传入db_pool
6. 实现初始化函数,在初始化函数中,将db_pool赋值self的属性
7. 实现process_item函数
    7.1  query = self.db_pool.runInteraction(执行插入数据操作的函数对象,函数需要参数),并接受执行返回结果
    7.2  query.addErrback(错误回调函数,函数需要参数),添加执行sql失败回调的函数,在回调函数中对错误数据进一步处理
8. 实现插入数据操作的函数,准备sql,执行sql
9. 实现错误回调函数,在回调函数中对错误数据进一步处理 

下面,我们以天堂图片网为例,大致熟悉一下异步存储:

1. 在存储之前,可以选择手动创建数据库(表名、字段名、字段类型等自己定义),也可以选择代码创建。

2. 存储数据之前还得先拿到数据

import scrapy
from ..items import ImgItem
class IvskySpider(scrapy.Spider):
  name = 'ivsky'
  allowed_domains = ['ivsky.com']
  start_urls = ['http://www.ivsky.com/tupian/ziranfengguang/']
  def parse(self, response):
    imgs = response.xpath('//div[@class="il_img"]/a/img')
    for img in imgs:
      alt = img.xpath('@alt').extract_first('')
      src = img.xpath('@src').extract_first('')
      item = ImgItem()
      item['alt'] = alt
      item['src'] = src
 
      yield item

3. 自定义item,并把数据传进去

import scrapy
 
class IvskySpiderItem(scrapy.Item):
  # define the fields for your item here like:
  # name = scrapy.Field()
  pass
 
class ImgItem(scrapy.Item):
 
  alt = scrapy.Field()
  src = scrapy.Field()

4. 接下来就是settings中的配置,代码如下(robots协议记得改为False):

MYSQL_HOST = '127.0.0.1'
MYSQL_USER = 'root'
MYSQL_PW = '123456'
MYSQL_DB = 'ivskydb'
MYSQL_CHARSET = 'utf8'

5. 再然后自定义pipeline,并把该pipeline在settings中配置(设置优先级):

from twisted.enterprise import adbapi
from pymysql import cursors
 
class TwistedMysqlPipeline(object):
 
  # 在调用TwistedMysqlPipeline时,第一个调用该函数
  @classmethod
  def from_settings(cls, settings):
 
    #准备需要用到的链接mysql的参数
    db_prams = dict(
      host=settings['MYSQL_HOST'],
      user=settings['MYSQL_USER'],
      password=settings['MYSQL_PW'],
      db=settings['MYSQL_DB'],
      port=3306,
      use_unicode=True,
      charset=settings['MYSQL_CHARSET'],
      # 指定使用的游标类型
      cursorclass=cursors.DictCursor
    )
    # 创建连接池对象,需要传入两个参数
    # 1.使用操作mysql第三方包名
    # 2.连接数据库需要的参数
    db_pool = adbapi.ConnectionPool('pymysql', **db_prams)
 
    return cls(db_pool)
 
  def __init__(self, db_pool):
    # 将连接池对象赋值self.db_pool属性
    self.db_pool = db_pool
 
  def process_item(self, item, spider):
 
    # 准备sql
    # 执行sql
    # 执行一个将item数据写入数据库的动作
    # 1.执行操作的函数
    # 2.执行函数需要的参数....
    query = self.db_pool.runInteraction(self.insert_item, item)
    # 执行sql出现异常错误时,回调的函数
    query.addErrback(self.handle_error, item, spider)
 
    return item
 
  # 插入数据出现错误时,回调的函数
  def handle_error(self, failure, item, spider):
    print(failure)
    print(item)
 
  # 执行插入数据的函数
  def insert_item(self, cursor, item):
    # 创建sql
    sql = "INSERT INTO ivs(alt,src)VALUES(%s,%s)"
    # 执行sql
    cursor.execute(sql,(item['alt'], item['src']))

6. pipeline在settings中的配置

ITEM_PIPELINES = {
  # 'ivsky_spider.pipelines.MysqlPipeline': 300,
  'ivsky_spider.pipelines.TwistedMysqlPipeline': 300,
}

代码到这里就结束了。

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

Python 相关文章推荐
Python实现的数据结构与算法之快速排序详解
Apr 22 Python
Python多进程并发(multiprocessing)用法实例详解
Jun 02 Python
python装饰器深入学习
Apr 06 Python
详解Django中间件的5种自定义方法
Jul 26 Python
对pandas的算术运算和数据对齐实例详解
Dec 22 Python
python读取目录下最新的文件夹方法
Dec 24 Python
python 用所有标点符号分隔句子的示例
Jul 15 Python
python实现最小二乘法线性拟合
Jul 19 Python
Python scrapy爬取小说代码案例详解
Jul 09 Python
13个Pandas实用技巧,助你提高开发效率
Aug 19 Python
pycharm配置安装autopep8自动规范代码的实现
Mar 02 Python
numpy数据类型dtype转换实现
Apr 24 Python
利用Python半自动化生成Nessus报告的方法
Mar 19 #Python
python实现手机销售管理系统
Mar 19 #Python
Python使用修饰器进行异常日志记录操作示例
Mar 19 #Python
python学生管理系统学习笔记
Mar 19 #Python
Python操作rabbitMQ的示例代码
Mar 19 #Python
Python Matplotlib实现三维数据的散点图绘制
Mar 19 #Python
浅谈python中get pass用法
Mar 19 #Python
You might like
如何做到打开一个页面,过几分钟自动转到另一页面
2007/04/20 Javascript
javascript 避免闭包引发的问题
2009/03/17 Javascript
jQuery源码分析-03构造jQuery对象-工具函数
2011/11/14 Javascript
JSON语法五大要素图文介绍
2012/12/04 Javascript
jquery.boxy弹出框(后隔N秒后自动隐藏/自动跳转)
2013/01/15 Javascript
jQuery对象和Javascript对象之间转换的实例代码
2013/03/20 Javascript
利用NodeJS的子进程(child_process)调用系统命令的方法分享
2013/06/05 NodeJs
jQuery实现单击弹出Div层窗口效果(可关闭可拖动)
2015/09/19 Javascript
js仿微博实现统计字符和本地存储功能
2015/12/22 Javascript
Jquery实现select multiple左右添加和删除功能的简单实例
2016/05/26 Javascript
jQuery动态加载css文件实现方法
2016/06/15 Javascript
原生JS实现的跳一跳小游戏完整实例
2019/01/27 Javascript
JS中async/await实现异步调用的方法
2019/08/28 Javascript
微信小程序自定义底部弹出框动画
2020/11/18 Javascript
忘记ftp密码使用python ftplib库暴力破解密码的方法示例
2014/01/22 Python
Python制作钉钉加密/解密工具
2016/12/07 Python
Python3使用PyQt5制作简单的画板/手写板实例
2017/10/19 Python
tensorflow 使用flags定义命令行参数的方法
2018/04/23 Python
selenium + python 获取table数据的示例讲解
2018/10/13 Python
python 获取页面表格数据存放到csv中的方法
2018/12/26 Python
python @classmethod 的使用场合详解
2019/08/23 Python
Numpy 中的矩阵求逆实例
2019/08/26 Python
Python 可变类型和不可变类型及引用过程解析
2019/09/27 Python
Python 窗体(tkinter)下拉列表框(Combobox)实例
2020/03/04 Python
Python如何在main中调用函数内的函数方式
2020/06/01 Python
Pycharm调试程序技巧小结
2020/08/08 Python
python按照list中字典的某key去重的示例代码
2020/10/13 Python
使用CSS3的rem属性制作响应式页面布局的要点解析
2016/05/24 HTML / CSS
中国一家专注拼团的社交购物网站:拼多多
2018/06/13 全球购物
一道SQL存储过程面试题
2016/10/07 面试题
教师四风自我剖析材料
2014/09/30 职场文书
综合素质评价个性发展自我评价
2015/03/06 职场文书
荒岛余生观后感
2015/06/09 职场文书
Python django中如何使用restful框架
2021/06/23 Python
关于python中模块和重载的问题
2021/11/02 Python
了解Kubernetes中的Service和Endpoint
2022/04/01 Servers