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 cx_freeze打包工具处理问题思路及解决办法
Feb 13 Python
解决Python 遍历字典时删除元素报异常的问题
Sep 11 Python
利用python实现微信头像加红色数字功能
Mar 26 Python
Python实现获取本地及远程图片大小的方法示例
Jul 21 Python
Django为窗体加上防机器人的验证码功能过程解析
Aug 14 Python
Python 实现递归法解决迷宫问题的示例代码
Jan 12 Python
使用Django和Postgres进行全文搜索的实例代码
Feb 13 Python
Pycharm无法打开双击没反应的问题及解决方案
Aug 17 Python
python3.7.3版本和django2.2.3版本是否可以兼容
Sep 01 Python
Python加载数据的5种不同方式(收藏)
Nov 13 Python
pyspark对Mysql数据库进行读写的实现
Dec 30 Python
python爬虫scrapy框架的梨视频案例解析
Feb 20 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实现12306火车票余票查询和价格查询(12306火车票查询)
2014/01/14 PHP
PHPThumb图片处理实例
2014/05/03 PHP
php实现猴子选大王问题算法实例
2015/04/20 PHP
用PHP代码给图片加水印
2015/07/01 PHP
php语言的7种基本的排序方法
2020/12/28 PHP
Kindeditor编辑器添加图片上传水印功能(php代码)
2017/08/03 PHP
在b/s开发中经常用到的javaScript技术
2006/08/23 Javascript
javascript 写类方式之四
2009/07/05 Javascript
学习ExtJS border布局
2009/10/08 Javascript
JavaScript实现大数的运算
2014/11/24 Javascript
vue.js学习之递归组件
2016/12/13 Javascript
bootstrap——bootstrapTable实现隐藏列的示例
2017/01/14 Javascript
Node 自动化部署的方法
2017/10/17 Javascript
使用typescript开发angular模块并发布npm包
2018/04/19 Javascript
jQuery实现获取form表单内容及绑定数据到form表单操作分析
2018/07/03 jQuery
[33:23]Secret vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
[41:17]VG vs Optic 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
[01:02:07]Liquid vs Newbee 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
用Python将动态GIF图片倒放播放的方法
2016/11/02 Python
Python内置函数delattr的具体用法
2017/11/23 Python
使用Python的Dataframe取两列时间值相差一年的所有行方法
2018/07/10 Python
Python实现个人微信号自动监控告警的示例
2019/07/03 Python
基于Python的接口自动化读写excel文件的方法
2021/01/15 Python
使用HTML5做个画图板的方法介绍
2013/05/03 HTML / CSS
基于HTML5 Canvas的3D动态Chart图表的示例
2017/11/02 HTML / CSS
QA工程师岗位职责
2013/11/20 职场文书
卫生安全检查制度
2014/02/04 职场文书
校长新学期寄语2016
2015/12/04 职场文书
适合青年人白手起家的创业项目分享
2019/08/16 职场文书
CSS3 制作的悬停缩放特效
2021/04/13 HTML / CSS
Python 制作自动化翻译工具
2021/04/25 Python
详解Django的MVT设计模式
2021/04/29 Python
JS中一些高效的魔法运算符总结
2021/05/06 Javascript
MySQL 8.0 之不可见列的基本操作
2021/05/20 MySQL
浅谈由position属性引申的css进阶讨论
2021/05/25 HTML / CSS
你知道Java Spring的两种事务吗
2022/03/16 Java/Android