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二叉树遍历的实现方法
Nov 21 Python
Python cookbook(数据结构与算法)从任意长度的可迭代对象中分解元素操作示例
Feb 13 Python
解决python nohup linux 后台运行输出的问题
May 11 Python
python numpy 部分排序 寻找最大的前几个数的方法
Jun 27 Python
pytorch训练imagenet分类的方法
Jul 27 Python
浅谈python中真正关闭socket的方法
Dec 18 Python
通过pykafka接收Kafka消息队列的方法
Dec 27 Python
python字符串和常用数据结构知识总结
May 21 Python
python web框架 django wsgi原理解析
Aug 20 Python
Python实现word2Vec model过程解析
Dec 16 Python
解决导入django_filters不成功问题No module named 'django_filter'
Jul 15 Python
Python collections模块的使用方法
Oct 09 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开发留言板的CRUD(增,删,改,查)操作
2012/04/19 PHP
详解PHP导入导出CSV文件
2014/11/03 PHP
Laravel实现用户注册和登录
2015/01/23 PHP
PHP面向对象程序设计之构造方法和析构方法详解
2019/06/13 PHP
在Javascript中 声明时用"var"与不用"var"的区别
2013/04/15 Javascript
js捕获鼠标滚轮事件代码
2013/12/16 Javascript
JavaScript四种调用模式和this示例介绍
2014/01/02 Javascript
Javascript代码实现仿实例化类
2015/04/03 Javascript
javascript实现炫酷的拖动分页
2015/05/11 Javascript
基于Jquery easyui 选中特定的tab
2015/11/17 Javascript
JS实现支持Ajax验证的表单插件
2016/03/24 Javascript
Vue报错:Uncaught TypeError: Cannot assign to read only property’exports‘ of object’#‘的解决方法
2017/06/17 Javascript
Node.js简单入门前传
2017/08/21 Javascript
Vue官网todoMVC示例代码
2018/01/29 Javascript
详解Vue.js中.native修饰符
2018/04/24 Javascript
[02:55]含熏伴清风,风行者至宝、屠夫身心及典藏宝瓶二展示
2020/09/08 DOTA
零基础写python爬虫之神器正则表达式
2014/11/06 Python
Python中自定义函数的教程
2015/04/27 Python
使用Python脚本实现批量网站存活检测遇到问题及解决方法
2016/10/11 Python
利用python实现凯撒密码加解密功能
2020/03/31 Python
调整Jupyter notebook的启动目录操作
2020/04/10 Python
Python脚本打包成可执行文件过程解析
2020/10/20 Python
python 如何停止一个死循环的线程
2020/11/24 Python
罗德与泰勒百货官网:Lord & Taylor
2016/08/12 全球购物
中国电子产品外贸网站:MiniIntheBox
2017/02/06 全球购物
Vichy薇姿加拿大官网:法国药妆,全球专业敏感肌护肤领先品牌
2018/07/11 全球购物
研究生求职推荐信范文
2013/11/30 职场文书
洗发露广告词
2014/03/14 职场文书
无毒社区工作方案
2014/05/23 职场文书
2014年法制宣传日活动方案
2014/11/02 职场文书
百年孤独读书笔记
2015/06/29 职场文书
小组组名及励志口号
2015/12/24 职场文书
企业愿景口号
2015/12/25 职场文书
使用 JavaScript 制作页面效果
2021/04/21 Javascript
OpenCV-Python实现怀旧滤镜与连环画滤镜
2021/06/09 Python
GO中sync包自由控制并发示例详解
2022/08/05 Golang