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 14 Python
用map函数来完成Python并行任务的简单示例
Apr 02 Python
Python简单定义与使用二叉树示例
May 11 Python
Python日期时间模块datetime详解与Python 日期时间的比较,计算实例代码
Sep 14 Python
python 遍历列表提取下标和值的实例
Dec 25 Python
python 浅谈serial与stm32通信的编码问题
Dec 18 Python
Python包,__init__.py功能与用法分析
Jan 07 Python
python使用Word2Vec进行情感分析解析
Jul 31 Python
Django路由层URLconf作用及原理解析
Sep 24 Python
如何基于Python和Flask编写Prometheus监控
Nov 25 Python
Python读取ini配置文件传参的简单示例
Jan 05 Python
Python爬虫:从m3u8文件里提取小视频的正确操作
May 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
php中把美国时间转为北京时间的自定义函数分享
2014/07/28 PHP
PDO防注入原理分析以及注意事项
2015/02/25 PHP
php无法连接mysql数据库的正确解决方法
2016/07/01 PHP
javascript中"/"运算符常见错误
2010/10/13 Javascript
javascript使用数组的push方法完成快速排序
2014/09/15 Javascript
jQuery实现非常实用漂亮的select下拉菜单选择效果
2015/11/06 Javascript
用自定义图片代替原生checkbox实现全选,删除以及提交的方法
2016/10/18 Javascript
bootstrap 模态框(modal)实现水平垂直居中显示
2017/01/23 Javascript
实例详解JavaScript中setTimeout函数的执行顺序
2017/07/12 Javascript
JS 实现banner图片轮播效果(鼠标事件)
2017/08/04 Javascript
JS获取日期的方法实例【昨天,今天,明天,前n天,后n天的日期】
2017/09/28 Javascript
nodejs通过钉钉群机器人推送消息的实现代码
2019/05/05 NodeJs
原生javascript自定义input[type=radio]效果示例
2019/08/27 Javascript
安装多版本Vue-CLI的实现方法
2020/03/24 Javascript
Python 解析XML文件
2009/04/15 Python
Python天气预报采集器实现代码(网页爬虫)
2012/10/07 Python
linux系统使用python获取内存使用信息脚本分享
2014/01/15 Python
在Python中使用Mako模版库的简单教程
2015/04/08 Python
在Python的一段程序中如何使用多次事件循环详解
2017/09/07 Python
python学习基础之循环import及import过程
2018/04/22 Python
利用Python如何生成便签图片详解
2018/07/09 Python
Python读取excel指定列生成指定sql脚本的方法
2018/11/28 Python
5款Python程序员高频使用开发工具推荐
2019/04/10 Python
2019 Python最新面试题及答案16道题
2019/04/11 Python
Python使用微信接入图灵机器人过程解析
2019/11/04 Python
Python定时从Mysql提取数据存入Redis的实现
2020/05/03 Python
Python+Kepler.gl轻松制作酷炫路径动画的实现示例
2020/06/02 Python
美国南部最大的家族百货公司:Belk
2017/01/30 全球购物
澳大利亚领先的宠物用品商店:VetSupply
2017/09/08 全球购物
车工岗位职责
2013/11/26 职场文书
大学社团活动策划书
2014/01/26 职场文书
安全技术说明书
2014/05/09 职场文书
委托书范本
2014/09/13 职场文书
依法行政工作汇报
2014/10/28 职场文书
【海涛教你打dota】体验一超神发条:咱是抢盾专业户
2022/04/01 DOTA
台积电称即便经济低迷也没有降价的计划
2022/04/21 数码科技