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(Tornado)模拟登录小米抢手机
Nov 12 Python
Python调用微信公众平台接口操作示例
Jul 08 Python
python hbase读取数据发送kafka的方法
Dec 27 Python
利用Python半自动化生成Nessus报告的方法
Mar 19 Python
解决pyinstaller打包发布后的exe文件打开控制台闪退的问题
Jun 21 Python
Python 3 判断2个字典相同
Aug 06 Python
python+rsync精确同步指定格式文件
Aug 29 Python
Python 脚本的三种执行方式小结
Dec 21 Python
解决Python3.8用pip安装turtle-0.0.2出现错误问题
Feb 11 Python
pandas DataFrame运算的实现
Jun 14 Python
详解Python直接赋值,深拷贝和浅拷贝
Jul 09 Python
python3 删除所有自定义变量的操作
Apr 08 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读取文件内容至字符串中,同时去除换行、空行、行首行尾空格(Zjmainstay原创)
2012/07/31 PHP
jQuery+Ajax+PHP“喜欢”评级功能实现代码
2015/10/08 PHP
文件编码导致jquery失效的解决方法
2013/06/26 Javascript
Jquery.addClass始终无效原因分析
2013/09/08 Javascript
JavaScript实现继承的4种方法总结
2014/10/16 Javascript
javascript实现简单的进度条
2015/07/02 Javascript
javascript入门教程基础篇
2015/11/16 Javascript
七个不允许错过的jQuery小技巧
2015/12/21 Javascript
JQuery异步提交表单与文件上传功能示例
2017/01/12 Javascript
JQuery通过后台获取数据遍历到前台的方法
2018/08/13 jQuery
基于Node.js的大文件分片上传示例
2019/06/19 Javascript
15分钟学会vue项目改造成SSR(小白教程)
2019/12/17 Javascript
javascript中的相等操作符(==与===区别)
2019/12/21 Javascript
react结合bootstrap实现评论功能
2020/05/30 Javascript
python抓取某汽车网数据解析html存入excel示例
2013/12/04 Python
详解在Python中处理异常的教程
2015/05/24 Python
合并百度影音的离线数据( with python 2.3)
2015/08/04 Python
python if not in 多条件判断代码
2016/09/21 Python
python实现决策树分类算法
2017/12/21 Python
pandas重新生成索引的方法
2018/11/06 Python
python实现文本界面网络聊天室
2018/12/12 Python
python的sorted用法详解
2019/06/25 Python
Selenium启动Chrome时配置选项详解
2020/03/18 Python
意大利在线大学图书馆:Libreria universitaria
2019/07/16 全球购物
怎样比较两个类型为String的字符串
2016/08/17 面试题
陈欧广告词
2014/03/14 职场文书
《云房子》教学反思
2014/04/20 职场文书
加油口号大全
2014/06/13 职场文书
2014年9.18纪念日演讲稿
2014/09/14 职场文书
说谎欺骗人检讨书300字
2014/11/18 职场文书
先进单位申报材料
2014/12/25 职场文书
行政助理岗位职责
2015/02/10 职场文书
中学生清明节演讲稿
2015/03/18 职场文书
入党自传范文2015
2015/06/26 职场文书
KTV员工管理制度
2015/08/06 职场文书
国庆节主题班会
2015/08/15 职场文书