使用item pipeline处理保存数据
一个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处理保存数据的更多相关文章
- scrapy学习笔记(三):使用item与pipeline保存数据
scrapy下使用item才是正经方法.在item中定义需要保存的内容,然后在pipeline处理item,爬虫流程就成了这样: 抓取 --> 按item规则收集需要数据 -->使用pip ...
- 如何用item pipeline(管道)清洗数据
版权声明:本文为博主原创文章,转载请注明出处:如果博客中有错误之处抑或有可以改进的地方,欢迎在评论区留言. https://blog.csdn.net/f156207495/article/detai ...
- Python爬虫从入门到放弃(十六)之 Scrapy框架中Item Pipeline用法
当Item 在Spider中被收集之后,就会被传递到Item Pipeline中进行处理 每个item pipeline组件是实现了简单的方法的python类,负责接收到item并通过它执行一些行为, ...
- 二、Item Pipeline和Spider-----基于scrapy取校花网的信息
Item Pipeline 当Item在Spider中被收集之后,它将会被传递到Item Pipeline,这些Item Pipeline组件按定义的顺序处理Item. 每个Item Pipeline ...
- Item Pipeline
当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理. 每个item pipeline组件(有时称之为"Item Pi ...
- Scrapy爬虫框架第七讲【ITEM PIPELINE用法】
ITEM PIPELINE用法详解: ITEM PIPELINE作用: 清理HTML数据 验证爬取的数据(检查item包含某些字段) 去重(并丢弃)[预防数据去重,真正去重是在url,即请求阶段做] ...
- Scrapy学习篇(七)之Item Pipeline
在之前的Scrapy学习篇(四)之数据的存储的章节中,我们其实已经使用了Item Pipeline,那一章节主要的目的是形成一个笼统的认识,知道scrapy能干些什么,但是,为了形成一个更加全面的体系 ...
- Scrapy框架学习(三)Spider、Downloader Middleware、Spider Middleware、Item Pipeline的用法
Spider有以下属性: Spider属性 name 爬虫名称,定义Spider名字的字符串,必须是唯一的.常见的命名方法是以爬取网站的域名来命名,比如爬取baidu.com,那就将Spider的名字 ...
- 6-----Scrapy框架中Item Pipeline用法
当Item 在Spider中被收集之后,就会被传递到Item Pipeline中进行处理 每个item pipeline组件是实现了简单的方法的python类,负责接收到item并通过它执行一些行为, ...
随机推荐
- 分布式事务 spring 两阶段提交 tcc
请问分布式事务一致性与raft或paxos协议解决的一致性问题是同一回事吗? - 知乎 https://www.zhihu.com/question/275845393 分布式事务11_TCC 两阶段 ...
- HashMap深度解析(转载)
原文地址:http://blog.csdn.net/ghsau/article/details/16890151 实现原理:用一个数组来存储元素,但是这个数组存储的不是基本数据类型.HashMap实现 ...
- MongoDB操作(1)—MongoDB java驱动核心层次结构及操作流程
MongoDB之java驱动学习 预备: 本地运行MongoDB采用默认端口20717: 安装MongoDB驱动: 以下关键步骤. 核心层次结构或步骤: 创建连接池:MongoClient实例. 对于 ...
- Dart语法基础
hello world // Define a function. printNumber(num aNumber) { print('The number is $aNumber.'); // Pr ...
- 牛客练习赛13E 乌龟跑步
题目链接:https://ac.nowcoder.com/acm/contest/70/E 题目大意: 略 分析: DP或记忆化搜索,个人觉得记忆化搜索比较好做,逻辑清晰,代码量少 代码如下: #in ...
- 996.ICU
996.ICU https://github.com/996icu/996.ICU https://www.zhihu.com/question/317722302 LICENSE https://g ...
- LR 场景选项配置--笔记
1 tools-options --设置关系到loadgenerator行为应用于一个场景中的所有的load generator 这些设置用于未来所有运行的场景并且通常只需要设置一次 2 expert ...
- ABP实践学习
一.
- telerik reporting报表
Telerik Reporting是一个非常人性化的控件,一个报表的生成几乎不用写代码,都是通过"所见即所得"模式完成.由于客户需要在实际的项目中运用Telerik Reporti ...
- 学习 Spring (六) 自动装配
Spring入门篇 学习笔记 No: (默认)不做任何操作 byName: 根据属性名自动装配.此选项将检查容器并根据名字查找与属性完全一致的 bean,并将其与属性自动装配 byType: 如果容器 ...