Scrapy中管道类的使用及如何将数据存储到MySQL数据库
在Scrapy中,我们知道管道是负责数据的清洗、保存。就是将每一个Item对象进行存储,一般在管道文件中一个管道类对应将一组数据存储到一个平台或者载体中。
所以今天的MySQL数据存储跟管道文件就不得不合起来说说了
前提条件:安装好了MySQL。没有安装MySQL的可以参考我博文 安装MySQL ,最好就是再安装一个 Navicat 图形化工具,后期操作起来更简单。
1.创建一个管道类
打开管道文件pipelien.py
, 添加一个存储到MySQL数据库中的一个管道类(),我们可以参照管道文件初始化中,自带的管道类<项目名称>Pipeline
写法,写一个MysqlPipeline
管道类。
# 一般在管道文件中一个管道类对应将一组数据存储到一个平台或者载体中
class MysqlPipeline(object):
def open_spider(self, spider):
pass
def process_item(self, item, spider):
...
return item
def close_spider(self, spider):
pass
细心的你会发现怎么多了
open_spider
和close_spider
两个方法。那他们是什么呢?干嘛用的?那原来的process_item
方法又是什么呢?带着一连串的疑问,往下看。
-
1.open_spider()
重写父类的一个方法:该方法只在开始爬虫时被调用一次
-
2.process_item()
该方法专门用来处理item类型对象,可以接收爬虫文件提交过来的item对象
该方法每接收到一个item就会被调用一次
-
3.close_spider()
重写父类的一个方法:该方法只在爬虫结束时被调用一次
原来是这样,弄清楚使用方法之后,那我们就开始工作吧。
我们通过上面的学习,了解了管道类中三个方法的使用,那现在是不是有思路了,我们可以在open_spider()
连接数据库;在process_item()
中,进行数据存储;在close_spider()
中关闭连接。
2.连接数据库
首先在open_spider()
连接数据库,代码中的mysql用户名
跟mysql密码
是当初我们安装MySQL时设置的。【前提工作:在MySQL数据库中新建一个数据库,因为在连接时需要指定一个数据库,进行连接配对,我这里的是cnblogs
数据库】
class MysqlPipeline(object):
conn = None
cursor = None
'''
host: 地址 本地的是127.0.0.1
port: 端口号 3306
user: mysql用户名
password: mysql密码
db: 数据库名
charset: 数据库编码(可选)
'''
def open_spider(self, spider):
# 进行异常处理,可能会因为我们的疏忽或者数据库的更改造成连接失败,所以,我们要对这部分代码块进行异常捕捉
try:
# 连接数据库
self.conn = pymysql.Connect(host='127.0.0.1', port=3306, user='root', password='LJ199912150', db='cnblogs',charset='utf8')
print('连接成功<<')
except Exception as e:
print(f'连接失败!!>>{e}')
exit() # 可以直接结束运行,按需求来设定
3.数据存储
【前提工作:在上面新建的那个数据库中,新建一个表,因为存储数据需要指定一张表,例如下面示例代码,表名叫news
, 里面有news_title
跟news_poster
两个字段】
在下面代码块,其中self.cursor.execute('mysql操作语法')
,我这里演示的是增加操作,其他的也相对应有注释,相信看这篇博客的小伙伴,mysql跟python也是有基础的,self.cursor.execute('mysql操作语法')
里面的内容也是能看懂的,就是将item提交过来数据,通过mysql语法进行添加到数据库中。
def process_item(self, item, spider):
# 创建游标
self.cursor = self.conn.cursor()
try:
# 插入数据
self.cursor.execute(
'INSERT INTO news (news_title, news_poster) VALUES("{}", "{}")'.format(item['news_title'], item['news_poster']))
print(f"文章<{item['news_title']}>数据提交中...")
# 数据提交到数据库
self.conn.commit()
except Exception as e:
print(f">>存储失败>>文章<{item['news_title']}>{e}")
self.conn.rollback()
return item
4.关闭游标跟连接
def close_spider(self, spider):
# 先关闭游标
self.cursor.close()
# 再关闭连接
self.conn.close()
【1、2、3、4步完整代码】
在管道文件(pipelines)中连接数据库进行数据存储的完整代码如下:
class MysqlPipeline(object):
conn = None
cursor = None
'''
host: 地址 本地的是127.0.0.1
port: 端口号 3306
user: 用户名
password: 密码
db: 数据库名
charset: 数据库编码(可选)
'''
def open_spider(self, spider):
# 进行异常处理,可能会因为我们的疏忽或者数据库的更改造成连接失败,所以,我们要对这部分代码块进行异常捕捉
try:
# 连接数据库
self.conn = pymysql.Connect(host='127.0.0.1', port=3306, user='root', password='LJ19991215', db='cnblogs',
charset='utf8')
print('连接成功<<')
except Exception as e:
print(f'连接失败!!>>{e}')
exit() # 可以直接结束运行,按需求来设定
def process_item(self, item, spider):
# 创建游标
self.cursor = self.conn.cursor()
try:
# 插入数据
self.cursor.execute(
'INSERT INTO news (news_title, news_poster) VALUES("{}", "{}")'.format(item['news_title'], item['news_poster']))
print(f"文章<{item['news_title']}>数据提交中...")
# 数据提交到数据库
self.conn.commit()
except Exception as e:
print(f">>存储失败>>文章<{item['news_title']}>{e}")
self.conn.rollback()
return item
def close_spider(self, spider):
# 先关闭游标
self.cursor.close()
# 再关闭连接
self.conn.close()
5.开启MySQL管道类
**【这一点也是最容易忘记操作的点】**进入settings
配置文件,找到ITEM_PIPELINES = {...}
,取消注释。
关于开启管道,这也是数据存储的关键,它就像一扇闸门。ITEM_PIPELINES = {...}
里面的管道类对应的值越小,优先级越高,在程序运行的时候,会越快被执行。
取消注释,我们可以看到初始化默认的管道类,现在我们要将我们自己定义的MySQL管道类添加进去,我们参照上面初始化的管道类来写就是, 'Cnblogs.pipelines.MysqlPipeline': 301,
添加完成之后,再次运行你的scrapy项目,程序运行结束之后,我们刷新下数据库,可以看到数据已经存储进去了。
拓展
通过上面学习我们知道,开启管道,能将爬虫文件中爬取的item
提交到pipelines
管道中,在之前操作,我们有两个管道类,一个初始的,一个是我们自定义的,并且在settings
设置中,设置了优先级,那item
进入优先级更高的管道类中之后,是怎么能继续传递给下一个管道类中的?
答案是通过 return item
进行传递的,我们知道在管道类中,process_item()
方法,是接收每一个提交过来的item
的,所以在这个方法的最后,我们添加return item
,这样在下一个被执行的管道类中,也能接收到item
,进行相应操作,否者将无法获取到item
。
所以在前期编写代码的时候,不管下面是否还有管道类,都添加一个return item
,养成好习惯嘛!
以上就是我目前所掌握的,如果有理解错误的,还请大佬在评论区指出来,非常感谢!
以上就是Scrapy中管道类的使用及如何将数据存储到MySQL数据库的所有内容了,点赞收藏加评论是最大的支持哦!
编写不易,转载请注明出处,如有侵权,请联系我!