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在hadoop上跑起来
Jan 27 Python
python中list列表的高级函数
May 17 Python
python3.4用循环往mysql5.7中写数据并输出的实现方法
Jun 20 Python
django项目运行因中文而乱码报错的几种情况解决
Nov 07 Python
Python实现多线程的两种方式分析
Aug 29 Python
python Matplotlib底图中鼠标滑过显示隐藏内容的实例代码
Jul 31 Python
opencv实现简单人脸识别
Feb 19 Python
浅析Python+OpenCV使用摄像头追踪人脸面部血液变化实现脉搏评估
Oct 17 Python
Python基于template实现字符串替换
Nov 27 Python
python 办公自动化——基于pyqt5和openpyxl统计符合要求的名单
May 25 Python
Django rest framework如何自定义用户表
Jun 09 Python
使用Python拟合函数曲线
Apr 14 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
Syphon 虹吸式咖啡壶冲煮–拨动法
2021/03/03 冲泡冲煮
php数据库连接
2006/10/09 PHP
PHP取整函数:ceil,floor,round,intval的区别详细解析
2013/08/31 PHP
php5.3不能连接mssql数据库的解决方法
2014/12/27 PHP
php文件夹的创建与删除方法
2015/01/24 PHP
thinkphp3.2.0 setInc方法 源码全面解析
2018/01/29 PHP
深入理解JavaScript系列(13) This? Yes,this!
2012/01/18 Javascript
jqgrid 表格数据导出实例
2013/11/21 Javascript
导入extjs、jquery 文件时$使用冲突问题解决方法
2014/01/14 Javascript
JavaScript的RequireJS库入门指南
2015/07/01 Javascript
Javascript 字符串模板的简单实现
2016/02/13 Javascript
JS中对象与字符串的互相转换详解
2016/05/20 Javascript
JS动态的把左边列表添加到右边的实现代码(可上下移动)
2016/11/17 Javascript
微信小程序 利用css实现遮罩效果实例详解
2017/01/21 Javascript
Angularjs 实现移动端在线测评效果(推荐)
2017/04/05 Javascript
.net MVC+Bootstrap下使用localResizeIMG上传图片
2017/04/21 Javascript
yarn的使用与升级Node.js的方法详解
2017/06/04 Javascript
微信小程序 自定义弹窗实现过程(附代码)
2019/12/05 Javascript
JavaScript Image对象实现原理实例解析
2020/08/26 Javascript
浅谈机器学习需要的了解的十大算法
2017/12/15 Python
selenium python浏览器多窗口处理代码示例
2018/01/15 Python
pandas 实现将重复表格去重,并重新转换为表格的方法
2018/04/18 Python
django使用LDAP验证的方法示例
2018/12/10 Python
使用python去除图片白色像素的实例
2019/12/12 Python
Linux下升级安装python3.8并配置pip及yum的教程
2020/01/02 Python
Python实现UDP程序通信过程图解
2020/05/15 Python
Python中有几个关键字
2020/06/04 Python
Python爬虫新手入门之初学lxml库
2020/12/20 Python
上班早退检讨书
2014/01/09 职场文书
家长给孩子的表扬信
2014/01/17 职场文书
2015年大学辅导员工作总结
2015/05/12 职场文书
穆斯林的葬礼读书笔记
2015/06/26 职场文书
关于空气污染危害的感想
2015/08/11 职场文书
详解Go语言运用广度优先搜索走迷宫
2021/06/23 Python
Jackson 反序列化时实现大小写不敏感设置
2021/06/29 Java/Android
漫画「处刑少女的生存之道」第3卷封面公开
2022/03/21 日漫