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调用微信公众平台接口操作示例
Jul 08 Python
对变量赋值的理解--Pyton中让两个值互换的实现方法
Nov 29 Python
python实现自动网页截图并裁剪图片
Jul 30 Python
Python设计模式之迭代器模式原理与用法实例分析
Jan 10 Python
对python中类的继承与方法重写介绍
Jan 20 Python
python 对字典按照value进行排序的方法
May 09 Python
新手如何发布Python项目开源包过程详解
Jul 11 Python
详解Python中namedtuple的使用
Apr 27 Python
在主流系统之上安装Pygame的方法
May 20 Python
Python爬虫实例——爬取美团美食数据
Jul 15 Python
python 图像增强算法实现详解
Jan 24 Python
对pytorch中x = x.view(x.size(0), -1) 的理解说明
Mar 03 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自定义函数实现代码
2011/12/30 PHP
php 输出json及显示json中的中文汉字详解及实例
2016/11/09 PHP
php正则提取html图片(img)src地址与任意属性的方法
2017/02/08 PHP
php解决安全问题的方法实例
2019/09/19 PHP
Thinkphp5.0 框架视图view的比较标签用法分析
2019/10/12 PHP
浅谈laravel数据库查询返回的数据形式
2019/10/21 PHP
Javascript 检测键盘按键信息及键码值对应介绍
2013/01/03 Javascript
jquery zTree异步加载简单实例分享
2013/02/05 Javascript
一个支付页面DEMO附截图
2014/07/22 Javascript
JavaScript从数组中删除指定值元素的方法
2015/03/18 Javascript
js获取form的方法
2015/05/06 Javascript
js 求时间差的实现代码
2016/04/26 Javascript
js阻止浏览器默认行为的简单实例
2016/05/15 Javascript
微信小程序 开发之顶部导航栏实例代码
2017/02/23 Javascript
javascript html5轻松实现拖动功能
2017/03/01 Javascript
AngularJS使用拦截器实现的loading功能完整实例
2017/05/17 Javascript
用js将long型数据转换成date型或datetime型的实例
2017/07/03 Javascript
vue element项目引入icon图标的方法
2018/06/06 Javascript
微信小程序学习笔记之登录API与获取用户信息操作图文详解
2019/03/29 Javascript
[00:35]DOTA2上海特级锦标赛 VP战队宣传片
2016/03/04 DOTA
Python的Flask框架中web表单的教程
2015/04/20 Python
Python 实现一个颜色色值转换的小工具
2016/12/06 Python
python中文分词,使用结巴分词对python进行分词(实例讲解)
2017/11/14 Python
Python通过Pygame绘制移动的矩形实例代码
2018/01/03 Python
python3.6使用pymysql连接Mysql数据库
2018/05/25 Python
Pycharm 实现下一个文件引用另外一个文件的方法
2019/01/17 Python
解决Python命令行下退格,删除,方向键乱码(亲测有效)
2020/01/16 Python
PHP面试题及答案一
2012/06/18 面试题
白酒市场营销方案
2014/02/25 职场文书
政治表现评语
2014/05/04 职场文书
综治维稳工作汇报
2014/10/27 职场文书
职工培训工作总结
2015/08/10 职场文书
党校团干班培训心得体会
2016/01/06 职场文书
创业计划书之酒厂
2019/10/14 职场文书
Django集成富文本编辑器summernote的实现步骤
2021/05/31 Python
Java并发编程之详解CyclicBarrier线程同步
2021/06/23 Java/Android