笔记-twisted-adbapi-scrapy-mysql

1.      异步插入mysql

在爬虫中需要insert到mysql,但有一个问题是在爬虫环境中commit的及时性与性能冲突。

一般可以在close_spider进行commit,这样做的问题是如果中途数据库崩了,数据丢失,找起来也很麻烦;

但如果在insert_db中直接加入commit,又会使程序执行变得很慢。

这里就可以使用Twisted中提供的以异步方式多线程访问数据库的模块adbapi,可以显著提供程序访问数据库的效率。

adbapi.ConnectionPool方法可以创建一个数据库连接池对象,其中包括多个连接对象,每个连接对象在独立的线程中工作。adbapi只是提供了异步访问数据库的编程框架,再其内部依然使MySQLdb这样的库访问数据库。

dbpool.runInteraction(insert_db,item)以异步方式调用insert_db函数,dbpool会选择连接池中的一个连接对象在独立线程中调用insert_db,其中参数item会被传给insert_db的第二个参数,传给insert_db的第一个参数是一个Transaction对象,其借口与Cursor对象类似,可以调用execute方法执行SQL语句,insert_db执行后,连接对象会自动调用commit方法

1.1.    代码示例

import pymysql
import pymysql.cursors
from twisted.enterprise import adbapi

# 同步插入
class ZhihuPipeline(object):
    """
   
数据保存到mysql
    同步保存
    """

def __init__(self, conn,
cursor):
        self.conn = conn
        self.cursor
=cursor

@classmethod
    def from_settings(cls,
settings):
        """

:param settings:
       
:return:
        """
       
db_parms = dict(
            host=settings['MYSQL_HOST'],
            user=settings['MYSQL_USER'],
            password=settings['MYSQL_PASSWORD'],
            database=settings['MYSQL_DB'],
        )

#连接池connectionpool
       
conn =
pymysql.connect( **db_parms )
        cursor = conn.cursor()
        return cls(conn, cursor)

def process_item(self, item, spider):
        """
       
同步保存
       
:param item:
       
:param spider:
       
:return:
        """
       
insert_sql = 'insert
into {}'
.format()
        self.cursor.execute(inert_sql)
        self.conn.commit()

def close_spider(self,spider):
        """
       
清理
       
:param spider:
       
:return:
        """
       
self.cursor.close()
        self.conn.close()

# 异步插入
class ZhihuPipelineTwisted(object):
    """
   
数据保存到mysql
    使用了twisted进行异步操作
   
"""
   
def __init__(self,
dbpool):
        self.dbpool =
dbpool

@classmethod
    def from_settings(cls,
settings):
        """
       
:param settings:
       
:return:
        """
       
db_parms = dict(
            host=settings['MYSQL_HOST'],
            user=settings['MYSQL_USER'],
            password=settings['MYSQL_PASSWORD'],
            database=settings['MYSQL_DB'],
            cursorclass=pymysql.cursors.DictCursor
        )

#连接池connectionpool
       
dbpool =
adbapi.ConnectionPool("pymysql",
**dbparms)
        return cls(dbpool)

def process_item(self, item,
spider):
        """

:param item:
       
:param spider:
       
:return:
        """
       
query = self.dbpool.runInteraction(self.do_insert,
item)
        query.addErrback(self.handle_error,
item, spider)

def do_insert(self, cursor,
item):
        insert_sql, params = 'insert
into {} ({}) values ({})'
       
cursor.execute(insert_sql,
params)

@staticmethod
    def handle_error(failure,
item, spider):
        # 处理插入异常
       
print(failure)

def close_spider(self,spider):
        """
       
提交及清理
       
:param spider:
       
:return:
        """
       
self.cursor.close()
        self.conn.close()

2.     
总结

adbapi为什么性能高,有空看下它是怎么优化整个执行逻辑的。

笔记-twisted-adbapi-scrapy的更多相关文章

  1. 笔记-twisted

    笔记-twisted 1.      简介 Twisted is an event-driven networking engine written in Python and licensed un ...

  2. 笔记-twisted源码-import reactor解析

    笔记-twisted源码-import reactor解析 1.      twisted源码解析-1 twisted reactor实现原理: 第一步: from twisted.internet ...

  3. twisted 模拟scrapy调度循环

    """模拟scrapy调度循环 """from ori_test import pr_typeimport loggingimport ti ...

  4. Scrapy笔记:使用scrapy shell url时出现403错误的解决办法

    参考 : http://www.th7.cn/Program/Python/201704/1154208.shtml 原因是网站的防爬虫配置起到了作用 (1):第一种方法是在命令上加上-s USER_ ...

  5. Scrapy基础01

    一.Scarpy简介 Scrapy基于事件驱动网络框架 Twisted 编写.(Event-driven networking) 因此,Scrapy基于并发性考虑由非阻塞(即异步)的实现. 参考:武S ...

  6. Python Scrapy环境配置教程+使用Scrapy爬取李毅吧内容

    Python爬虫框架Scrapy Scrapy框架 1.Scrapy框架安装 直接通过这里安装scrapy会提示报错: error: Microsoft Visual C++ 14.0 is requ ...

  7. 第8章 scrapy进阶开发(2)

    8-4 selenium集成到scrapy中 其实也没什么好说的直接上代码 这是在middlewares.py中定义的一个class: from selenium.common.exceptions ...

  8. scrapy 和 scrapy_redis 安装

    安装sqlslte,scrapy需要这个模块 yum install sqlite-devel python3.5 下载包自己编译安装 ./configure make make install 自带 ...

  9. [转]使用scrapy进行大规模抓取

    原文:http://www.yakergong.net/blog/archives/500 使用scrapy有大概半年了,算是有些经验吧,在这里跟大家讨论一下使用scrapy作为爬虫进行大规模抓取可能 ...

  10. windows 安装 Scrapy的套路

    我最近在琢磨scrapy爬虫框架,在windows中安装scrapy遇到了不少坑:直接 pip install scrapy 安装不成功的,百度说要安装vc2008+等等,安装这些时间太长,最后找到一 ...

随机推荐

  1. OpenGL中的数据——Buffer

    OpenGL中主要包括了两种数据——Buffer和Texture. Buffer用于储存线性数无类型据块,可以看成普通的内存块,而Texture则用于储存多维数据,一般储存图像或者其他数据. Buff ...

  2. ANT 的Table表格样式修改方法

    注:(大家在给页面添加参数或者方法的时候,记得写上注释,方便别人查看) 1.表格行选中样式添加:(可以去beijing,精子库质控统计查看例子) (咱们以前页面上的表格都是在hover时显示选中效果, ...

  3. LA 4256 商人

    题目链接:https://vjudge.net/contest/160916#problem/B 题意:给一个无向图,和一个序列:要求,在这个序列中,两两相连的两个数相同,或者,在无向图中相邻:(n& ...

  4. 一个有意思的标签<marquee>

    marquee标签不是HTML3.2的一部分,并且只支持MSIE3以后内核,所以如果你使用非IE内核浏览器(如:Netscape)可能无法看到下面一些很有意思的效果,该标签是个容器标签.  一.mar ...

  5. 关于eclipse中引入项目报错或者没有JRE System Library问题(jre报错)或者jre1.7(8)改为jre1.8(7)等问题

    解决方法: 右键项目工程-->>properties->>java bulid path -->>>libraries -->>add libra ...

  6. MVC学习一:MVC简单流程

    MVC学习一:MVC初次接触 1.MVC简单流程 1.1.服务器接收客户端请求后,解析URL(根据 路由表里配置的URL来分析 类名(控制器名)和方法名)根据请求的类名,创建对应的控制器类对象,并调用 ...

  7. Storm 中drpc调用

    package storm.starter; import backtype.storm.Config; import backtype.storm.LocalCluster; import back ...

  8. C# 通过socket实现UDP 通信

    UDP不属于面向连接的通信,在选择使用协议的时候,选择UDP必须要谨慎.在网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重.但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小, ...

  9. Anaconda的使用—Spyder常用快捷键

    Ctrl + 1: 注释/反注释 Ctrl + 4/5: 块注释/块反注释 Ctrl + L: 跳转到行号 Tab/Shift + Tab: 代码缩进/反缩进 Ctrl +I:显示帮助

  10. Angularjs基础(五)

    AngularJS Select(选项框) AngularJS 可是使用数组或对象创建一个下拉列表选项.使用ng-options创建选项框 在AngularJS 中我们可以使用ng-option指令来 ...