爬虫+数据保存2

爬取数据保存到MySQL数据库

这篇文章, 我们来讲解如何将我们爬虫爬取到的数据, 进行保存, 而且是把数据保存到MySQL数据库的方式去保存。

目录

1.使用pymysql连接数据库并执行插入数据sql代码(insert)

2.优化pymysql数据库连接以及插入功能代码

3.爬取双色球网站的数据并保存到MySQL数据库中

4.利用面向对象的写法进行爬虫并保存数据

一、使用pymysql连接数据库并执行插入数据sql代码(insert)

如果我们没有安装过pymysql这个库的话, 我们在终端里面安装一下:

cmd 复制代码
pip install pymysql

安装完这个安装包之后, 我们在代码里面导入这个包

代码:

python 复制代码
import pymysql

使用python连接数据库代码(创建一个连接对象):

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。

创建游标对象:

python 复制代码
cur = conn.cursor()  # 游标对象cursor

往stu表中添加一条数据(插入数据):

python 复制代码
# sql语句
sql = 'INSERT INTO stu VALUES (null,"xiaoyao",18);' # 没有指定字段,代表当前往表添加一条数据,字段值必须要全部加上
# sql = 'INSERT INTO stu(name) VALUES ("xiaoyao")' # 指定了字段,代表当前往表中添加一条数据,字段名和字段值的个数保持一致
# 关键字全大写 非关键字全小写

执行sql语句:

python 复制代码
cur.execute(sql)

进行commit提交(执行的是添加,修改,删除,需要配合commit进行提交):

python 复制代码
conn.commit()

这里必须要commit提交, 否则数据库里面的数据不会变。

关闭资源:

python 复制代码
cur.close() # 关闭游标
conn.close() # 关闭数据库连接

游标和数据库连接必须都关闭, 否则会浪费资源。这个是写代码的常识, 必须养成这样的习惯。

完整代码:

python 复制代码
'''
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......这些关键字去优化连接数据库以及插入数据操作。

优化代码:

python 复制代码
'''
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解析数据。

代码:

python 复制代码
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数据库中)的代码转换为面向对象的形式去写代码。

这些代码, 不一定要掌握, 学有余地的同学可以去研究下哦!!!

代码:

python 复制代码
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数据库的所有内容了, 如果有哪里不懂的地方,可以把问题打在评论区, 欢迎大家在评论区交流!!!

如果我有写错的地方, 望大家指正, 也可以联系我, 让我们一起努力, 继续不断的进步.

学习是个漫长的过程, 需要我们不断的去学习并掌握消化知识点, 有不懂或概念模糊不理解的情况下,一定要赶紧的解决问题, 否则问题只会越来越多, 漏洞也就越老越大.

人生路漫漫, 白鹭常相伴!!!

相关推荐
祝余Eleanor5 分钟前
Day37 模型可视化与推理
人工智能·python·深度学习
sg_knight6 分钟前
Python 面向对象基础复习
开发语言·python·ai编程·面向对象·模型
自在极意功。9 分钟前
InnoDB 存储引擎的逻辑存储结构深度解析
mysql·innodb·b+树·索引
dhdjjsjs32 分钟前
Day35 PythonStudy
python
张洪权1 小时前
RBAC 菜单查询的“标准写法”
mysql
如竟没有火炬1 小时前
四数相加贰——哈希表
数据结构·python·算法·leetcode·散列表
背心2块钱包邮1 小时前
第9节——部分分式积分(Partial Fraction Decomposition)
人工智能·python·算法·机器学习·matplotlib
木盏1 小时前
三维高斯的分裂
开发语言·python
乘风!1 小时前
服务器上部署的Mysql,服务器上可登录成功,远程电脑无法连接的
mysql
a程序小傲1 小时前
京东Java面试被问:ZGC的染色指针如何实现?内存屏障如何处理?
java·后端·python·面试