一个Item Pipeline 不需要继承特定基类,只需要实现某些特定方法,面向接口。

class MyPipeline(object):
def __init__(self):
"""
可选实现,做参数初始化等
""" def process_item(self, item, spider):
"""
该方法必须实现,每个item pipeline组件都需要调用该方法,
该方法必须返回一个 Item 对象,被丢弃的item将不会被之后的pipeline组件所处理。
:param item: 被爬取的item
:param spider: 爬取该item的spider debug查看类属性
:return:
"""
return item def open_spider(self, spider):
"""
可选实现,当spider被开启时,这个方法被调用。
:param spider: 被开启的spider
:return:
""" def close_spider(self, spider):
"""
可选实现,当spider被关闭时,这个方法被调用
:param spider: 被关闭的spider
:return:
"""

  

采用同步的机制写入数据:

class MysqlPipeline(object):
def __init__(self):
pass def process_item(self, item, spider):
if isinstance(item,InstanceItem):
save(item)
if spider.name == "spider_name":
save(item)

  

采用异步的机制写入代码

class MysqlTwistedPipeline(object):
# 采用异步的机制写入mysql
def __init__(self, dbpool):
self.dbpool = dbpool @classmethod
def from_settings(cls, settings):
"""
from_settings 激活pipeline之后,会自动调用该函数加载settings中的配置
:param settings:
:return:
"""
dbparms = dict(
host="127.0.0.1", # settings["MYSQL_HOST"],
db="spider", # settings["MYSQL_DBNAME"],
user="root", # settings["MYSQL_USER"]
password="root", # settings["MYSQL_PASSWORD"],
charset="utf8",
use_unicode=True, # 不然没办法保存中文
cursorclass=cursors.DictCursor
)
db_pool = adbapi.ConnectionPool('pymysql', **dbparms)
return cls(db_pool) def process_item(self, item, spider):
##使用twisted将mysql插入变成异步执行
query = self.dbpool.runInteraction(self.do_insert, item)
query.addErrback(self.handle_error, item, spider) # 处理异常 def handle_error(self, failure, item, spider):
# 处理异步插入的异常
print(failure) def do_insert(self, cursor, item):
# 执行具体的插入
# 根据不同的的item构建不同的sql语句插入到mysql中
insert_sql, params = item.get_insert_sql() cursor.execute(insert_sql, params)
# 自动commit

数据库连接异常

pymysql.err.InterfaceError: (0, '')

原因:数据库操作对象实例未注销,但持有的数据库连接已失效,导致后续数据库操作无法进行。

解决:在每次插入数据之前检测连接是否可用Connection.ping()。

其实sqlalchemy就有这个处理,原生pymysql则需要自行处理。

下面是代码

from twisted.enterprise import adbapi
from pymysql import cursors def get_db_pool():
dbparms = dict(
host=MYSQL_HOST,
port=MYSQL_PORT,
db=MYSQL_DBNAME,
user=MYSQL_USER,
password=MYSQL_PASSWORD,
charset="utf8",
use_unicode=True, # 不然没办法保存中文
cursorclass=cursors.DictCursor
)
db_pool = adbapi.ConnectionPool('pymysql', **dbparms)
return db_pool class MysqlTwistedPipeline(object):
# 采用异步的机制写入mysql
def __init__(self, dbpool):
self.dbpool = dbpool @classmethod
def from_settings(cls, settings):
"""
from_settings 激活pipeline之后,会自动调用该函数加载settings中的配置
:param settings:
:return:
"""
db_pool = get_db_pool()
return cls(db_pool) def process_item(self, item, spider):
##使用twisted将mysql插入变成异步执行
query = self.dbpool.runInteraction(self.do_insert, item)
query.addErrback(self.handle_error, item, spider) # 处理异常 def handle_error(self, failure, item, spider):
# 处理异步插入的异常
print(failure) def do_insert(self, cursor, item):
# 执行具体的插入
# 根据不同的的item构建不同的sql语句插入到mysql中
conn = cursor.connection
try:
conn.ping()
except:
self.dbpool.close()
self.dbpool = get_db_pool() insert_sql, params = item.get_insert_sql()
cursor.execute(insert_sql, params)

使用item pipeline处理保存数据的更多相关文章

  1. scrapy学习笔记(三):使用item与pipeline保存数据

    scrapy下使用item才是正经方法.在item中定义需要保存的内容,然后在pipeline处理item,爬虫流程就成了这样: 抓取 --> 按item规则收集需要数据 -->使用pip ...

  2. 如何用item pipeline(管道)清洗数据

    版权声明:本文为博主原创文章,转载请注明出处:如果博客中有错误之处抑或有可以改进的地方,欢迎在评论区留言. https://blog.csdn.net/f156207495/article/detai ...

  3. Python爬虫从入门到放弃(十六)之 Scrapy框架中Item Pipeline用法

    当Item 在Spider中被收集之后,就会被传递到Item Pipeline中进行处理 每个item pipeline组件是实现了简单的方法的python类,负责接收到item并通过它执行一些行为, ...

  4. 二、Item Pipeline和Spider-----基于scrapy取校花网的信息

    Item Pipeline 当Item在Spider中被收集之后,它将会被传递到Item Pipeline,这些Item Pipeline组件按定义的顺序处理Item. 每个Item Pipeline ...

  5. Item Pipeline

    当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理. 每个item pipeline组件(有时称之为"Item Pi ...

  6. Scrapy爬虫框架第七讲【ITEM PIPELINE用法】

    ITEM PIPELINE用法详解:  ITEM PIPELINE作用: 清理HTML数据 验证爬取的数据(检查item包含某些字段) 去重(并丢弃)[预防数据去重,真正去重是在url,即请求阶段做] ...

  7. Scrapy学习篇(七)之Item Pipeline

    在之前的Scrapy学习篇(四)之数据的存储的章节中,我们其实已经使用了Item Pipeline,那一章节主要的目的是形成一个笼统的认识,知道scrapy能干些什么,但是,为了形成一个更加全面的体系 ...

  8. Scrapy框架学习(三)Spider、Downloader Middleware、Spider Middleware、Item Pipeline的用法

    Spider有以下属性: Spider属性 name 爬虫名称,定义Spider名字的字符串,必须是唯一的.常见的命名方法是以爬取网站的域名来命名,比如爬取baidu.com,那就将Spider的名字 ...

  9. 6-----Scrapy框架中Item Pipeline用法

    当Item 在Spider中被收集之后,就会被传递到Item Pipeline中进行处理 每个item pipeline组件是实现了简单的方法的python类,负责接收到item并通过它执行一些行为, ...

随机推荐

  1. Jenkins Installing and migration

    JAVA_Zookeeper_hadoop - CSDN博客https://blog.csdn.net/wangmuming Installing Jenkins on Red Hat distrib ...

  2. C#复习笔记(3)--C#2:解决C#1的问题(泛型)

    这一章会描述在C#2中所做的主要的变化 泛型 泛型的概念中包含类型参数和类型实参,类型参数相当于类型实参的蓝图. 泛型类型分为未绑定泛型类型和已构造泛型类型.已构造泛型类型又分为开放的泛型类型和封闭的 ...

  3. java中的标记接口(标签接口)

    Java中的标记接口(Marker Interface),又称标签接口(Tag Interface),具体是不包含任何方法的接口.在Java中很容易找到标记接口的例子,比如JDK中的Serialzab ...

  4. 理解git工作区和暂存区

    版本库 在工作区目录中有一个.git文件,这个其实不是工作区而是Git的版本库 版本库中包含两个部分,一个是暂存区index/stage,另一个是git自动为我们创建的第一个分支master,以及一个 ...

  5. Azure系列2.1.5 —— BlobOutputStream

    (小弟自学Azure,文中有不正确之处,请路过各位大神指正.) 网上azure的资料较少,尤其是API,全是英文的,中文资料更是少之又少.这次由于公司项目需要使用Azure,所以对Azure的一些学习 ...

  6. Android——线程通讯 Handler、Looper、Message;

    线程通讯问题 (主要用到了Handler类,Looper类和Message类以及MessageQueue) 在Android中主线程如何向子线程中发送消息的问题.让我们来想想,这其中的过程,无非就是创 ...

  7. Swagger2常用注解及其说明 (转)

    Api 用在Controller中,标记一个Controller作为swagger的文档资源 属性名称 说明 value Controller的注解 description 对api资源的描述 hid ...

  8. mycat - 全局序列

    解决主键冲突问题:例如id自增的order表,如果分布式情况下不处理的话,当每个表的第一条数据id都是1. 怎么确保id唯一呢? 解决办法: 1.本地文件(不推荐) 2.数据库方式(推荐) 3.时间戳 ...

  9. Django--CRM--modelformset的用法

    一 . modelformset用法 其实和modelform方法差不多,只不过是显示的时候可以直接修改,显示的select的那种模式 from django.forms import modelfo ...

  10. Linux基础学习(15)--启动管理

    第十五章——启动管理 一.CentOS 6.x启动管理 1.系统运行级别: (1)运行级别: (2)运行级别命令: (3)系统默认运行级别: 2.系统启动过程: . 二.启动引导程序grub 1.Gr ...