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 文件和输入输出小结
Oct 09 Python
vc6编写python扩展的方法分享
Jan 17 Python
Python 3.x 新特性及10大变化
Jun 12 Python
python 自定义对象的打印方法
Jan 12 Python
Python3日期与时间戳转换的几种方法详解
Jun 04 Python
使用Python画股票的K线图的方法步骤
Jun 28 Python
python 进程的几种创建方式详解
Aug 29 Python
Python运行异常管理解决方案
Mar 09 Python
Python unittest 自动识别并执行测试用例方式
Mar 09 Python
Python pandas如何向excel添加数据
May 22 Python
opencv 查找连通区域 最大面积实例
Jun 04 Python
Python实现生成bmp图像的方法
Jun 13 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
用php和MySql来与ODBC数据连接
2006/10/09 PHP
PHP中COOKIES使用示例
2015/07/26 PHP
聊聊 PHP 8 新特性 Attributes
2020/08/19 PHP
javascript高亮效果的二种实现方法
2008/09/14 Javascript
jquery 操作DOM案例代码分享
2012/04/05 Javascript
javascript对象的使用和属性操作示例详解
2014/03/02 Javascript
Jquery Post处理后不进入回调的原因及解决方法
2014/07/15 Javascript
Javascript中获取对象的原型对象的方法小结
2015/02/25 Javascript
JS面向对象(3)之Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法
2016/02/25 Javascript
javascript基础知识之html5轮播图实例讲解(44)
2017/02/17 Javascript
详谈js模块化规范
2017/07/07 Javascript
Express使用html模板的详细代码
2017/09/18 Javascript
layui中layer前端组件实现图片显示功能的方法分析
2017/10/13 Javascript
vue使用element-ui的el-input监听不了回车事件的解决方法
2018/01/12 Javascript
Vue中对比scoped css和css module的区别
2018/05/17 Javascript
解决vue打包css文件中背景图片的路径问题
2018/09/03 Javascript
[56:47]Ti4 循环赛第三日 iG vs Liquid
2014/07/12 DOTA
[01:35]2014DOTA2西雅图邀请赛 专访狐狸妈青春献给刀塔
2014/07/08 DOTA
python 控制语句
2011/11/03 Python
使用Pyrex来扩展和加速Python程序的教程
2015/04/13 Python
Python爬虫实现百度图片自动下载
2018/02/04 Python
Python实现正弦信号的时域波形和频谱图示例【基于matplotlib】
2018/05/04 Python
Python 使用PIL numpy 实现拼接图片的示例
2018/05/08 Python
python利用ffmpeg进行录制屏幕的方法
2019/01/10 Python
python正则表达式的懒惰匹配和贪婪匹配说明
2020/07/13 Python
英国领先的家庭时尚品牌:Peacocks
2018/01/11 全球购物
WiFi云数码相框:Nixplay
2018/07/05 全球购物
美国按摩椅批发网站:Titan Chair
2018/12/27 全球购物
Linux如何为某个操作添加别名
2013/03/01 面试题
资深生产主管自我评价
2013/09/22 职场文书
大学生实习证明范本
2014/01/15 职场文书
网吧最新创业计划书范文
2014/03/27 职场文书
科长竞聘演讲稿
2014/05/16 职场文书
积极向上的团队口号
2014/06/06 职场文书
2015年重阳节活动主持词
2015/07/30 职场文书
关于JavaScript回调函数的深入理解
2021/06/27 Javascript