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中实现定制类的特殊方法总结
Sep 28 Python
Python实现豆瓣图片下载的方法
May 25 Python
python制作爬虫并将抓取结果保存到excel中
Apr 06 Python
python write无法写入文件的解决方法
Jan 23 Python
Python pickle模块实现对象序列化
Nov 22 Python
Python模块相关知识点小结
Mar 09 Python
PyTorch中torch.tensor与torch.Tensor的区别详解
May 18 Python
Python API 操作Hadoop hdfs详解
Jun 06 Python
Python使用文件操作实现一个XX信息管理系统的示例
Jul 02 Python
Python 制作查询商品历史价格的小工具
Oct 20 Python
Django model class Meta原理解析
Nov 14 Python
python中用ggplot绘制画图实例讲解
Jan 26 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和ACCESS写聊天室(八)
2006/10/09 PHP
php Ubb代码编辑器函数代码
2012/07/05 PHP
PHP判断图片格式的七种方法小结
2013/06/03 PHP
基于php实现随机合并数组并排序(原排序)
2015/11/26 PHP
PHP简单读取PDF页数的实现方法
2016/07/21 PHP
PHP7.3.10编译安装教程
2019/10/08 PHP
laravel 5.5 关闭token的3种实现方式
2019/10/24 PHP
php开发最强大的IDE编辑的phpstorm 2020.2配置Xdebug调试的详细教程
2020/08/17 PHP
JavaScript 动态改变图片大小
2009/06/11 Javascript
html中table数据排序的js代码
2011/08/09 Javascript
JavaScript分析、压缩工具JavaScript Analyser
2014/12/31 Javascript
Javascript核心读书有感之类型、值和变量
2015/02/11 Javascript
JavaScript动态修改弹出窗口大小的方法
2015/04/06 Javascript
jQuery mobile转换url地址及获取url中目录部分的方法
2015/12/04 Javascript
Javascript for in的缺陷总结
2017/02/03 Javascript
JS匹配日期和时间的正则表达式示例
2017/05/12 Javascript
Nodejs 识别图片类型的方法
2019/08/15 NodeJs
package.json各个属性说明详解
2020/03/11 Javascript
JavaScript多种图形实现代码实例
2020/06/28 Javascript
小程序实现列表展开收起效果
2020/07/29 Javascript
详解Howler.js Web音频播放终极解决方案
2020/08/23 Javascript
从源码角度来回答keep-alive组件的缓存原理
2021/01/18 Javascript
python将html转成PDF的实现代码(包含中文)
2013/03/04 Python
Python中不同进制互相转换(二进制、八进制、十进制和十六进制)
2015/04/05 Python
Python中矩阵库Numpy基本操作详解
2017/11/21 Python
python shapely.geometry.polygon任意两个四边形的IOU计算实例
2020/04/12 Python
pycharm下pyqt4安装及环境配置的教程
2020/04/24 Python
django 模版关闭转义方式
2020/05/14 Python
python mongo 向数据中的数组类型新增数据操作
2020/12/05 Python
解决python3.6用cx_Oracle库连接Oracle的问题
2020/12/07 Python
教师求职信范文分享
2013/12/27 职场文书
党校培训自我鉴定
2014/02/01 职场文书
报表员工作失误检讨书范文
2014/09/19 职场文书
领导班子在批评与自我批评座谈会上的发言
2014/09/28 职场文书
办理收楼委托书范本
2014/10/09 职场文书
精神病医院见习报告
2014/11/03 职场文书