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 相关文章推荐
Mac OS X10.9安装的Python2.7升级Python3.3步骤详解
Dec 04 Python
在Django的URLconf中进行函数导入的方法
Jul 18 Python
Python字符串匹配算法KMP实例
Jul 18 Python
python web框架学习笔记
May 03 Python
python处理Excel xlrd的简单使用
Sep 12 Python
ActiveMQ:使用Python访问ActiveMQ的方法
Jan 30 Python
Python下应用opencv 实现人脸检测功能
Oct 24 Python
Python 异步协程函数原理及实例详解
Nov 13 Python
python如何提取英语pdf内容并翻译
Mar 03 Python
Python在后台自动解压各种压缩文件的实现方法
Nov 10 Python
彻底解决Python包下载慢问题
Nov 15 Python
Python之多进程与多线程的使用
Feb 23 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 5.3.0 安装分析心得
2009/08/07 PHP
PHP 程序员的调试技术小结
2009/11/15 PHP
解析PHP缓存函数的使用说明
2013/05/10 PHP
Swoole 5将移除自动添加Event::wait()特性详解
2019/07/10 PHP
PHP 实现base64编码文件上传出现问题详解
2020/09/01 PHP
js脚本学习 比较实用的基础
2006/09/07 Javascript
验证javascript中Object和Function的关系的三段简单代码
2010/06/27 Javascript
JavaScript中获取元素索引的函数
2010/09/10 Javascript
基于jquery ajax 用户无刷新登录方法详解
2012/04/28 Javascript
js简易namespace管理器 实例代码
2013/06/21 Javascript
jQuery中:checked选择器用法实例
2015/01/04 Javascript
JavaScript 面向对象与原型
2015/04/10 Javascript
js显示文本框提示文字的方法
2015/05/07 Javascript
jQuery实现下滑菜单导航效果代码
2015/08/25 Javascript
vue.js的提示组件
2017/03/02 Javascript
angular+bootstrap的双向数据绑定实例
2017/03/03 Javascript
初识NodeJS服务端开发入门(Express+MySQL)
2017/04/07 NodeJs
关于element-ui的隐藏组件el-scrollbar的使用
2019/05/29 Javascript
jQuery实现B2B网站后台管理系统侧导航
2020/07/08 jQuery
[20:21]《一刀刀一天》第十六期:TI国际邀请赛正式打响,总奖金超过550万
2014/05/23 DOTA
[02:58]魔廷新尊——痛苦女王至宝语音台词节选
2020/06/14 DOTA
跟老齐学Python之用Python计算
2014/09/12 Python
python实现多线程抓取知乎用户
2016/12/12 Python
对Python中DataFrame选择某列值为XX的行实例详解
2019/01/29 Python
使用python接入微信聊天机器人
2020/03/31 Python
python3.7将代码打包成exe程序并添加图标的方法
2019/10/11 Python
Dr.Jart+美国官网:韩国药妆品牌
2019/01/18 全球购物
德国受欢迎的旅游和休闲网站:lastminute.de
2019/09/23 全球购物
中班下学期个人总结
2015/02/12 职场文书
单位推荐信范文
2015/03/27 职场文书
2015年度高中教师工作总结
2015/05/26 职场文书
值班管理制度范本
2015/08/06 职场文书
Go语言实现Snowflake雪花算法
2021/06/08 Golang
Python内置数据结构列表与元组示例详解
2021/08/04 Python
简述Java中throw-throws异常抛出
2021/08/07 Java/Android
【D4DJ】美少女DJ企划 动画将于明年冬季开播第2季
2022/04/11 日漫