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删除文件示例分享
Jan 28 Python
Python易忽视知识点小结
May 25 Python
Python中集合的内建函数和内建方法学习教程
Aug 19 Python
请不要重复犯我在学习Python和Linux系统上的错误
Dec 12 Python
简单实现python数独游戏
Mar 30 Python
对Python3中dict.keys()转换成list类型的方法详解
Feb 03 Python
python pygame实现滚动横版射击游戏城市之战
Nov 25 Python
基于Python实现简单学生管理系统
Jul 24 Python
深入分析python 排序
Aug 24 Python
利用Python的folium包绘制城市道路图的实现示例
Aug 24 Python
Python连接mysql方法及常用参数
Sep 01 Python
运行python提示no module named sklearn的解决方法
Nov 29 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实现上传文件并存进数据库的方法
2015/07/16 PHP
php微信公众号开发(2)百度BAE搭建和数据库使用
2016/12/15 PHP
PHP开发api接口安全验证操作实例详解
2020/03/26 PHP
Prototype 工具函数 学习
2009/07/23 Javascript
jquery实现倒计时代码分享
2014/06/13 Javascript
随鼠标移动的时钟非常漂亮遗憾的是只支持IE
2014/08/12 Javascript
window.onload与$(document).ready()的区别分析
2015/05/30 Javascript
Javascript对象Clone实例分析
2015/06/09 Javascript
JS实现黑色大气的二级导航菜单效果
2015/09/18 Javascript
基于jquery实现复选框全选,反选,全不选等功能
2015/10/16 Javascript
jquery.validate使用详解
2016/06/02 Javascript
浅谈angularJS中的事件
2016/07/12 Javascript
jquery实现放大镜简洁代码(推荐)
2017/06/08 jQuery
详解VueJS 数据驱动和依赖追踪分析
2017/07/26 Javascript
EasyUI的TreeGrid的过滤功能的解决思路
2017/08/08 Javascript
node跨域请求方法小结
2017/08/25 Javascript
原生JavaScript实现remove()和recover()功能示例
2018/07/24 Javascript
vue 使用自定义指令实现表单校验的方法
2018/08/28 Javascript
详解Vue项目中出现Loading chunk {n} failed问题的解决方法
2018/09/14 Javascript
手把手教你 CKEDITOR 4 实现Dialog 内嵌 IFrame操作详解
2019/06/18 Javascript
js实现超级玛丽小游戏
2020/03/18 Javascript
vue+element-ui表格封装tag标签使用插槽
2020/06/18 Javascript
WebStorm无法正确识别Vue3组合式API的解决方案
2021/02/18 Vue.js
[03:10]超级美酒第四天 fy拉比克秀 大合集
2018/06/05 DOTA
Python的collections模块中的OrderedDict有序字典
2016/07/07 Python
15行Python代码带你轻松理解令牌桶算法
2018/03/21 Python
python打包生成的exe文件运行时提示缺少模块的解决方法
2018/10/31 Python
详解如何设置Python环境变量?
2019/05/13 Python
tensorflow查看ckpt各节点名称实例
2020/01/21 Python
canvas离屏技术与放大镜实现代码示例
2018/08/31 HTML / CSS
美国大尺码女装零售商:TORRID
2016/10/01 全球购物
家得宝官网:The Home Depot(全球最大的家居装饰专业零售商)
2018/12/17 全球购物
Cynthia Rowley官网:全球领先的生活方式品牌
2020/10/27 全球购物
劳动实践课感言
2014/02/01 职场文书
开业庆典主持词
2014/03/21 职场文书
Python爬虫之爬取哔哩哔哩热门视频排行榜
2021/04/28 Python