python异步存储数据详解

在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,
}

代码到这里就结束了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 浅析Python中的序列化存储的方法

    在程序运行的过程中,所有的变量都是在内存中,比如,定义一个dict: d = dict(name='Bob', age=20, score=88) 可以随时修改变量,比如把name改成'Bill',但是一旦程序结束,变量所占用的内存就被操作系统全部回收.如果没有把修改后的'Bill'存储到磁盘上,下次重新运行程序,变量又被初始化为'Bob'. 我们把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshal

  • 将Python中的数据存储到系统本地的简单方法

    有很多时候,我们会在python的运行过程中得到一些重要的变量,比如一个数据量很庞大的dict.而且,后面的某些程序也会用到这个dict,那么我们就最好把它存储到本地来,然后下次调用的时候,先读取本地的文件,导入到字典类型中,调用即可.这样就免去了重新学习这个字典的过程.那么在python中如何把数据存储到本地呢? 我们用到的是python中的pickle模块. 如下: import pickle data1 = {'a': [1, 2.0, 3, 4+6j], 'b': ('string',

  • python异步存储数据详解

    在Python中,数据存储方式分为同步存储和异步存储.同步写入速度比较慢,而爬虫速度比较快,有可能导致数据保存不完整,一部分数据没有入库.而异步可以将爬虫和写入数据库操作分开执行,互不影响,所以写入速度比较快,能够保证数据的完整性. 异步存储数据库大致看分为以下步骤: 1. 在settings中配置Mysql链接需要的参数(主机地址.用户账号.密码.需要操作的表名.编码格式等) 2. 自定义Pipeline,实现from_settings函数 3. from twisted.enterprise

  • Angularjs的$http异步删除数据详解及实例

    Angularjs的$http异步删除数据详解及实例 有人会说删除这东西有什么可讲的,写个删除的service,controller调用一下不就完了. 嗯...看起来是这样,但是具体实现起来真的有这么简单吗?首先有以下几个坑 怎么确定数据是否删除成功? 怎么同步视图的数据库的内容? 1.思路 1.实现方式一 删除数据库中对应的内容,然后将$scope中的对应的内容splice 2.实现方式二 删除数据库中对应的内容,然后再reload一下数据(也就是再调用一次查询方法,这种消耗可想而知,并且还要

  • Python获取网页数据详解流程

    Requests 库是 Python 中发起 HTTP 请求的库,使用非常方便简单. 发送 GET 请求 当我们用浏览器打开东旭蓝天股票首页时,发送的最原始的请求就是 GET 请求,并传入url参数. import requests url='http://push2his.eastmoney.com/api/qt/stock/fflow/daykline/get' 用Python requests库的get函数得到数据并设置requests的请求头. header={ 'User-Agent'

  • 利用python如何处理nc数据详解

    前言 这两天帮一个朋友处理了些 nc 数据,本以为很简单的事情,没想到里面涉及到了很多的细节和坑,无论是"知难行易"还是"知易行难"都不能充分的说明问题,还是"知行合一"来的更靠谱些,既要知道理论又要知道如何实现,于是经过不太充分的研究后总结成此文,以记录如何使用 python 处理 nc 数据. 一.nc 数据介绍 nc 全称 netCDF(The Network Common Data Form),可以用来存储一系列的数组,就是这么简单(参考

  • Python如何处理JSON数据详解

    目录 什么是JSON? JSON作用 为什么使用JSON JSON的使用 最后 什么是JSON? JSON是一种轻量级的数据交互格式,采用完全独立于编程语言的文本格式来存储和表示数据.和xml相比,它更小巧,但描述能力却不差,更适合于在网络上传输数据. JSON是一种有着特殊格式的字符串,格式与对象或者数组是非常类似的,只不过属性名是带双引号的. JSON用于对象和数组的序列化.(序列化:格式转换)用于对象和数组与字符串进行相互转换. JSON作用 与 XML一样,它是格式化数据的一种方式.We

  • Python 列表筛选数据详解

    目录 总结 在做数据处理中,常会遇到列表筛选,比如有以下两个列表: 根据上列表中的KEY1 , 筛选下列表的数据,也就是标黄的数据.数量不大的情况,一般就是遍历比较,逻辑简单,几行代码搞掂. 但如果列表达到万,或者百万.千万,那遍历效率就低了. 先构造测试的列表. # 构造筛选目标列表,确保KEY不重复 n1 = 30000 n1_set = set([random.randint(1,n1) for n in range(n1)]) n1 = len(n1_set) list1 = [['11

  • 微信小程序 本地数据存储实例详解

    微信小程序 本地数据存储实例详解 前言 如果您在看此文章之前有过其他程序的开发经验,那一定会知道一般例如安卓或者苹果的原生APP都提供了本地的存储功能,甚至可以使用sqlite数据库来做存储.可是微信的小程序框架基于微信本身,其实际运行环境只是在浏览器里面,所以不会提供那么丰富的数据存储实力.但html5开始已经可以在浏览器里面存储数据,好在微信的小程序给这个功能封装好了,这样我们可以使用数据存储. 每个微信小程序都可以有自己的本地缓存,可以通过 wx.setStorage(wx.setStor

  • Python解析多帧dicom数据详解

    概述 pydicom是一个常用python DICOM parser.但是,没有提供解析多帧图的示例.本文结合相关函数和DICOM知识做一个简单说明. DICOM多帧数据存储 DICOM标准中关于多帧数据存储的最重要一部分说明是PS3.5 Annex A.4 A.4 Transfer Syntaxes For Encapsulation of Encoded Pixel Data. 无论何时,Pixel Data都存放在Pixel Data (7FE0,0010)中.有可能是直接存放的(nati

  • Python数据结构之图的存储结构详解

    一.图的定义 图是一种比树更复杂的一种数据结构,在图结构中,结点之间的关系是任意的,任意两个元素之间都可能相关,因此,它的应用极广.图中的数据元素通常被称为顶点 ( V e r t e x ) (Vertex) (Vertex), V V V是顶点的有穷非空集合, V R VR VR是两个顶点之间的关系的集合(可以为空),可以表示为图 G = { V , { V R } } G=\{V,\{VR\}\} G={V,{VR}}. 二.相关术语 2.1 无向图 给定图 G = { V , { E }

  • 利用Python多处理库处理3D数据详解

    今天我们将介绍处理大量数据时非常方便的工具.我不会只告诉您可能在手册中找到的一般信息,而是分享一些我发现的小技巧,例如tqdm与 multiprocessing​imap​​一起使用.并行处理档案.绘制和处理 3D 数据以及如何搜索如果您有点云,则用于对象网格中的类似对象.​ 那么我们为什么要求助于并行计算呢?如今,如果您处理任何类型的数据,您可能会面临与"大数据"相关的问题.每次我们有不适合 RAM 的数据时,我们都需要一块一块地处理它.幸运的是,现代编程语言允许我们生成在多核处理器

随机推荐