爬取数据保存到MySQL数据库
这篇文章, 我们来讲解如何将我们爬虫爬取到的数据, 进行保存, 而且是把数据保存到MySQL数据库的方式去保存。
目录
1.使用pymysql连接数据库并执行插入数据sql代码(insert)
2.优化pymysql数据库连接以及插入功能代码
3.爬取双色球网站的数据并保存到MySQL数据库中
4.利用面向对象的写法进行爬虫并保存数据
一、使用pymysql连接数据库并执行插入数据sql代码(insert)
如果我们没有安装过pymysql这个库的话, 我们在终端里面安装一下:
pip install pymysql
安装完这个安装包之后, 我们在代码里面导入这个包
代码:
import pymysql
使用python连接数据库代码(创建一个连接对象):
conn = pymysql.Connect(host='127.0.0.1', port=3306, user='root', password='root', database='spider38')
print(conn) # 连接对象
这里面的参数说明一下:
host, 这个就是ip, 我们连接本地电脑的数据库, 所以ip就是127.0.0.1(相当于localhost), port是端口, mysql默认端口就3306, user指的是用户名, password指的是密码, database指的是数据库名。指定参数值一个都不能少,并且一个都不能错。python中连接mysql的目的是为了对数据库的内容做操作
注意:在我们写代码之前, 我们自己给自己创建一个叫做spider38数据, 表格名叫做stu。
创建游标对象:
cur = conn.cursor() # 游标对象cursor
往stu表中添加一条数据(插入数据):
# sql语句
sql = 'INSERT INTO stu VALUES (null,"xiaoyao",18);' # 没有指定字段,代表当前往表添加一条数据,字段值必须要全部加上
# sql = 'INSERT INTO stu(name) VALUES ("xiaoyao")' # 指定了字段,代表当前往表中添加一条数据,字段名和字段值的个数保持一致
# 关键字全大写 非关键字全小写
执行sql语句:
cur.execute(sql)
进行commit提交(执行的是添加,修改,删除,需要配合commit进行提交):
conn.commit()
这里必须要commit提交, 否则数据库里面的数据不会变。
关闭资源:
cur.close() # 关闭游标
conn.close() # 关闭数据库连接
游标和数据库连接必须都关闭, 否则会浪费资源。这个是写代码的常识, 必须养成这样的习惯。
完整代码:
'''
mysql 本地安装 小皮
pip install pymysql
'''
import pymysql
# 连接mysql
'''
电脑中操作mysql的方式:
1- 终端链接mysql 通过命令操作
2- 利用可视化软件
'''
# 指定参数值一个都不能少,并且一个都不能错
conn = pymysql.Connect(host='127.0.0.1', port=3306, user='root', password='root', database='spider38')
print(conn) # 连接对象
# python中链接mysql的目的是为了对数据库的内容做操作
# 只能通过sql语句进行操作
# select * from 表;
# 如果想要执行sql语句,必须要通过游标对象完成
# 创建游标对象
cur = conn.cursor() # 游标对象
# 往stu表中添加一条数据
# 如果mysql中某个字段设置主键并且设置了自动增长,python的代码写法
# null 不是往数据库存入null而是以我设置的主键为主
sql = 'INSERT INTO stu VALUES (null,"xiaoyao",18);' # 没有指定字段,代表当前往表添加一条数据,字段值必须要全部加上
# sql = 'INSERT INTO stu(name) VALUES ("xiaoyao")' # 指定了字段,代表当前往表中添加一条数据,字段名和字段值的个数保持一致
# 关键字全大写 非关键字全小写
'''
执行的是添加,修改,删除,需要配合commit进行提交
'''
cur.execute(sql)
conn.commit()
# 关闭资源
cur.close()
conn.close()
运行结果:
我们再去Navicat看一下数据库里面的表格信息:
**
**
注意: 第31行的sql = 'INSERT INTO stu VALUES (null,“xiaoyao”,18);'这行代码, 在VALUES里面, 第一个参数写了null,这里null 不是往数据库存入null而是以我设置的主键为主。
二、优化pymysql数据库连接以及插入功能代码
我们在一的基础上, 加上try……execpt……finally……这些关键字去优化连接数据库以及插入数据操作。
优化代码:
'''
mysql 本地安装 小皮
pip install pymysql
'''
import pymysql
"""
解决的问题:
1- 只有当连接对象创建成功之后,才允许一定要被关闭
2- 执行sql语句,成功,则commit 失败,则rollback
"""
conn = 0
cur = 0
try:
conn = pymysql.Connect(host='127.0.0.1', port=3306, user='root', password='123456', database='spider38')
print(conn) # 连接对象
cur = conn.cursor() # 游标对象
sql = 'INSERT INTO stu VALUES (null,"xiaoyao",20);' # 没有指定字段,代表当前往表添加一条数据,字段值必须要全部加上
'''
执行的是添加,修改,删除,需要配合commit进行
提交
回滚
'''
cur.execute(sql)
conn.commit()
except Exception as e:
print('异常原因:',e)
if conn!=0:
conn.rollback()
finally:
print(conn)
# 当链接对象创建成功时才需要关闭,但是链接创建失败没有必要关闭
# 关闭资源 必须要执行
if conn!=0 and cur!=0:
print('当前连接已经被关闭')
cur.close()
conn.close()
在try里面, 是我们认为可能会出错的代码, except里面是当try里面的代码有错误的时候, except里面的代码才会执行, 而且我们通过except Exception as e还有print(‘异常原因:’,e)这两行代码打印异常原因。if conn != 0和conn.rollback()这两行代码指的是如果数据库连接已建立但出现异常,执行回滚操作,取消本次事务中的任何改变。finally里面的代码指的是无论是否发生异常都会执行。在finally里面, 执行的是关闭资源的代码, 如果数据库处于建立且连接状态而且游标也已建立的情况下, 关闭数据库连接和游标连接。
三、爬取双色球网站的数据并保存到MySQL数据库中
我们打开双色球网站:
我们需要爬取表格里面的所有数据。
我们打开开发者工具, 在里面寻找请求。
这里面第一个就是我们想要的请求。
这里我们还是使用html解析数据。
代码:
url = 'https://datachart.500.com/ssq/history/history.shtml'
import requests
from lxml import etree
import pymysql
res = requests.get(url)
res.encoding = 'gb2312'
tree = etree.HTML(res.text)
trs = tree.xpath('//tr[@class="t_tr1"]')
# print(len(trs))
conn = 0
cur = 0
try:
conn = pymysql.Connect(host='127.0.0.1', port=3306, user='root', password='root', database='spider38')
cur = conn.cursor() # 游标对象
for tr in trs:
# 基于表格的每一行,获取所有的列
tds = tr.xpath('./td/text()')
# 红球数据 [期号,]
red_nums = ','.join(tds[1:7])
# 列表切片,返回的结果还是一个列表,把列表转为字符串,【1,2】 "1,2"
sql = f'INSERT INTO ssq VALUES (null,"{red_nums}","{tds[7]}","{tds[8]}","{tds[9]}","{tds[10]}","{tds[11]}","{tds[12]}","{tds[13]}","{tds[14]}","{tds[15]}");'
cur.execute(sql)
conn.commit()
print(sql, '已经执行成功')
except Exception as e:
print('异常的原因:',e)
if conn!=0:
conn.rollback()
finally:
# print(conn)
# 当链接对象创建成功时才需要关闭,但是链接创建失败没有必要关闭
# 关闭资源 必须要执行
if conn!=0 and cur!=0:
print('当前连接已经被关闭')
cur.close()
conn.close()
运行结果:
打开Navicat查看数据库的ssq表格:
数据添加成功!!!
这里面我们还是用了xpath来爬虫, xpath用法在之前的文章中有讲到, 可以去翻我以前写过的爬虫博客。我们还是在代码当中使用了try……catch……finally……这种写法。
我们在网页的开发者工具里面, 查看元素:
我们发现我们想获取表格里面的数据, 是在一个表格的tr标签里面, 而且class为t_tr1, 所以就有了trs = tree.xpath(‘//tr[@class=“t_tr1”]’)这行代码, trs目前还是获取着所有类为t_tr1的tr标签, 所以我们需要遍历它, 用for tr in trs:这句话遍历所有类为t_tr1的tr标签, 然后再基于表格的每一行,获取所有的列, 就是tds = tr.xpath(‘./td/text()’)这行代码, 拿到红球数据[期号,] : red_nums = ‘,’.join(tds[1:7]), 将爬取到的数据, 插入到数据库的表格中, sql = f’INSERT INTO ssq VALUES (null,“{red_nums}”,“{tds[7]}”,“{tds[8]}”,“{tds[9]}”,“{tds[10]}”,“{tds[11]}”,“{tds[12]}”,“{tds[13]}”,“{tds[14]}”,“{tds[15]}”);', 列表切片,返回的结果还是一个列表,把列表转为字符串,【1,2】 “1,2”, 注意, 需要有cur.execute(sql)和conn.commit()这两行代码, 不然的话, 数据不会成功的添加到数据库当中, 这两节话的意思分别是执行sql语句和提交事务。后面的except和finally就不难理解了, except里面是当try里面的代码有错误的时候, except里面的代码才会执行, 而且我们通过except Exception as e还有print(‘异常原因:’,e)这两行代码打印异常原因。if conn != 0和conn.rollback()这两行代码指的是如果数据库连接已建立但出现异常,执行回滚操作,取消本次事务中的任何改变。finally里面的代码指的是无论是否发生异常都会执行。在finally里面, 执行的是关闭资源的代码, 如果数据库处于建立且连接状态而且游标也已建立的情况下, 关闭数据库连接和游标连接。
四、利用面向对象的写法进行爬虫并保存数据
将第三点(爬取双色球网站的数据并保存到MySQL数据库中)的代码转换为面向对象的形式去写代码。
这些代码, 不一定要掌握, 学有余地的同学可以去研究下哦!!!
代码:
import pymysql
import requests
from lxml import etree
class Spider:
# url headers host username port password database
def __init__(self, url, username, password, database):
self.url = url
self.username = username
self.password = password
self.database = database
self.headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'
}
self.host = '127.0.0.1'
self.port = 3306
self.conn = pymysql.Connect(host=self.host, port=self.port, user=username, password=password, database=database)
self.cur = self.conn.cursor()
# 发请求方法
def send_request(self):
res = requests.get(self.url, headers=self.headers)
res.encoding = 'gb2312'
# 调用解析方法,传入响应内容
self.parse(res.text)
# 解析方法
def parse(self, data): # data=响应的内容
# data = res.text
tree = etree.HTML(data)
trs = tree.xpath('//tr[@class="t_tr1"]')
for tr in trs:
# 基于表格的每一行,获取所有的列
tds = tr.xpath('./td/text()')
# 红球数据 [期号,]
# 调用保存方法,报存数据
self.save_mysql(tds)
# 保存方法
def save_mysql(self, tds): # tds = 页面中的每一条数据 列表
red_nums = ','.join(tds[1:7])
try:
sql = f'INSERT INTO ssq VALUES (null,"{red_nums}","{tds[7]}","{tds[8]}","{tds[9]}","{tds[10]}","{tds[11]}","{tds[12]}","{tds[13]}","{tds[14]}","{tds[15]}");'
self.cur.execute(sql)
self.conn.commit()
print(sql, '保存完毕')
except Exception as e:
print(e)
self.conn.rollback()
def close_conn(self):
self.cur.close()
self.conn.close()
# Spider(url,host,username,password,database)
url = 'https://datachart.500.com/ssq/history/history.shtml'
s = Spider(url, 'root', '123456', 'spider38')
# 调用请求方法 --》调用解析--》调用保存数据
s.send_request()
# 关闭资源方法
s.close_conn()
以上就是爬取数据保存到MySQL数据库的所有内容了, 如果有哪里不懂的地方,可以把问题打在评论区, 欢迎大家在评论区交流!!!
如果我有写错的地方, 望大家指正, 也可以联系我, 让我们一起努力, 继续不断的进步.
学习是个漫长的过程, 需要我们不断的去学习并掌握消化知识点, 有不懂或概念模糊不理解的情况下,一定要赶紧的解决问题, 否则问题只会越来越多, 漏洞也就越老越大.
人生路漫漫, 白鹭常相伴!!!