学python的第十九天

网络通信和访问数据库

1.1 基本的网络知识

@TCP/IP

       IP是低级的路由协议,它将数据拆分在许多小的数据包中,并通过网络将他们发送到某一特定地址,但无法保证所有包都抵达目的地,也不能保证包按顺序抵达

       TCP(传输控制协议),是一种高层协议,是面向连接的可靠数据传输协议,数据包未收到,会重发,并对数据包进行准确性检查,保证数据包按顺序抵达。

@IP地址,IPv4和IPv6

       特殊IP地址,127.0.0.1回送地址,只进行本机进程间通信,不进行任何网络传输

@端口(范围:0~65535,小于1024的保留给预定义的服务,如HTTP,80    FTP,20/21   Telnet,23   Email,25等等)

       网络通信程序运行提供网络服务或进行通信,需要不同的端口号进行通信,不仅要指定IP地址,还要指定端口号

@HTTP(端口80)/HTTPS(端口443)

HTTP(超文本传输协议)

HTTP/1.1共定义了8种请求方法,GET和POST方法最常用

HTTPS(超文本传输安全协议):HTTP+SSL,用于提供加密通信及对网络服务器身份的鉴定

1.2 搭建自己的Web服务器

1,安装JDK(java开发工具包)

2,配置java运行环境

3,安装Apache Tomcat服务器

4,启动Apache Tomcat服务器

1.3 urllib.request模块

1,发送GET请求

# 发送GET请求,获取响应
import urllib.request  # 导入urllib.request模块

url = 'http://www.baidu.com/?action=query&ID=10'   # 请求URL网址,?后的内容是请求参数,多个参数用&分隔,例如action是参数名,query是参数值

req = urllib.request.Request(url)  # 创建一个请求对象,默认是GET请求

with urllib.request.urlopen(req) as response:  # 发送请求,并获取响应对象,可是使用with as代码块管理和释放
    data = response.read()      # 读取数据,为字节序列数据
    json_data = data.decode()   # 将字节序列数据转换为字符串
    print(json_data)   # 输出字符串数据

2,发送POST请求,提交数据
# 发送POST请求,提交数据

import urllib.request  # 导入urllib.request模块

url = 'http://www.baidu.com/'

# 准备HTTP参数
params_dict = {'action': 'query', 'ID': '10'}
params_str = urllib.parse.urlencode(params_dict)  # 将字典转换为URL参数字符串
print(params_str)

# 字符串转换为字节序列数据
params_bytes = params_str.encode()

# 创建一个请求对象,设置请求方法为POST
req = urllib.request.Request(url, data=params_bytes)  # 发送POST请求,并设置请求方法为POST

with urllib.request.urlopen(req) as response:  # 发送请求,并获取响应对象,可使用with as代码块管理和释放
    data = response.read()      # 读取数据,为字节序列数据
    json_data = data.decode()   # 将字节序列数据转换为字符串
    print(json_data)   # 输出字符串数据

1.4 JSON数据 

JSON(JavaScript Object Notation)

构成JSON文档的两种结构为:JSON对象(object)和JSON数组(array)

@1.4.1 JSON对象类似于python中的字典类型

JSON数据中的解码(decode)指将JSON数据转换为python数据,当从网络中接收或从磁盘中读取JSON数据时,需要将其解码为Python数据

{

"name": "a.htm",

"size": "345",

"saved": "true"

}

@1.4.2 JSON数组类似于python中的列表类型,示例如下:

    "text","html","css"

]

@1.4.3 JSON的数值有字符串,数字,true,false,null,对象或数组。null表示空的对象,而且对象和数组可以嵌套

@1.4.4 使用json模块提供的loads(str)函数进行JSON数据的解码,参数str是JSON字符串,返回python数据。

代码示例:

import urllib.request  # 导入urllib.request模块
import json    # 导入json模块

url = 'http://www.baidu.com/?action=query&ID=10'   # 请求URL网址,?后的内容是请求参数,多个参数用&分隔,例如action是参数名,query是参数值

req = urllib.request.Request(url)  # 创建一个请求对象,默认是GET请求

with urllib.request.urlopen(req) as response:  # 发送请求,并获取响应对象,可是使用with as代码块管理和释放
    data = response.read()      # 读取数据,为字节序列数据
    json_data = data.decode()   # 将字节序列数据转换为字符串
    print('JSON字符串:', json_data)   # 输出字符串数据
    
    py_dict = json.load(json_data)   # 解码json字符串,返回字典
    print('备忘录ID:', py_dict['ID'])
    print('备忘录日期:', py_dict['CDate'])
    print('备忘录内容:', py_dict['Content'])
    print('用户ID:', py_dict['UserID'])
    

@1.4.5 下载图片示例

# 1.4 下载图片示例
import urllib.request  # 导入urllib.request模块

url = 'http://www.baidu.com/img/logo.png'

req = urllib.request.Request(url)  # 创建一个请求对象,默认是GET请求

with urllib.request.urlopen(req) as response:  # 发送请求,并获取响应对象,可使用with as代码块管理和释放
    data = response.read()  # 读取数据,为字节序列数据
    f_name = 'logo.png'  # 文件名
    with open(f_name, 'wb') as f:  # 创建文件对象,并设置写入模式,wb表示写入二进制数据
        f.write(data)  # 将字节序列数据写入文件
        print('图片下载完成')

@1.4.6 返回所有备忘录信息示例

# 1.5 返回所有备忘录信息
import urllib.request  # 导入urllib.request模块
import json

url = 'http://www.baidu.com/'  # 请求URL网址

req = urllib.request.Request(url)  # 创建一个请求对象,默认是GET请求

with urllib.request.urlopen(req) as response:  # 发送请求,并获取响应对象,可是使用with as代码块管理和释放
    data = response.read()  # 读取数据,为字节序列数据
    json_data = data.decode()  # 将字节序列数据转换为字符串

    py_dict = json.load(json_data)  # 解码json字符串,返回字典
    record_array = py_dict['Record']  # 获取备忘录数组

    for record_obj in record_array:
        print('--------备忘录信息--------')
        print('备忘录ID:', record_obj['ID'])
        print('备忘录日期:', record_obj['CDate'])
        print('备忘录内容:', record_obj['Content'])
        print('用户ID:', record_obj['UserID'])

2.1 SQLite数据库 

SQLite是嵌入式系统使用的关系数据库,目前的主流版本是SQLite 3。SQLite是开源的,采用C语言编写而成,具有可移植性强、可靠性高 、小而易用等特点。SQLite提供了对SQL-92标准的支持,支持多表、索引、事务、视图和触发。

@2.1.1 SQLite的数据类型,是无数据类型的数据库

支持的数据类型:

INTEGER(有符号的整数类型)

REAL(浮点类型)

TEXT(字符串类型,采用UTF-8,UTF-16)

BLOB(二进制大对象类型,能够存放任意二进制数据)

@2.1.2  Python数据类型与SQLite数据类型的映射

Python数据类型 SQLite数据类型
None NULL
int INTEGRE
float REAL
str TEXT
bytes BLOB

 @2.1.3 使用GUI管理工具管理SQLite数据库

如DB Browser for SQLite。

自行下载安装,打开后如下图

1. 创建数据库

2.创建数据表

3.执行SQL语句

4.浏览数据 

 2.2 数据库编程的基本操作

数据库编程主要分为两类:查询(Read)和修改(C插入,U更新,D删除)

查询数据和修改数据

2.3 sqlite3模块API(使用此模块访问数据库)

@ 2.3.1 数据库连接对象Connection

访问第一步是数据库连接

通过connect(database)函数建立数据库连接,参数database是SQLite数据库的文件路径,连接成功,返回数据库连接对象Connection。

Connection有如下重要方法:

close()关闭数据库连接,关闭之后再使用数据库连接将引发异常

commit()提交数据库事务

rollback()回滚数据库事务

cursor()获得Cursor游标对象

@ 2.3.2 游标对象Cursor

一个Cursor游标对象表示一个数据库游标,游标暂时保存了SQL操作所影响到的数据。游标是通过数据库连接创建的。

游标Cursor对象有很多方法和属性,其中的基本SQL操作方法如下:

execute(sql[,parameters]):执行一条SQL语句,sql是SQL语句 ,parameters是为SQL提供的参数,可以是序列或字典类型。返回值是 整数,表示执行SQL语句影响的行数。

executemany(sql[,seq_of_params]):执行批量SQL语句,sql是S QL语句,seq_of_params是为SQL提供的参数,seq_of_params是序列。 返回值是整数,表示执行SQL语句影响的行数。

在通过execute()和executemany()方法执行SQL查询语句后, 还要通过提取方法从查询结果集中返回数据,相关提取方法如下:

fetchone():从结果集中返回只有一条记录的序列,如果没有数 据,则返回None。

fetchmany(size=cursor.arraysize):从结果集中返回小于等于size 记录数的序列,如果没有数据,则返回空序列,size在默认情况下是整 个游标的行数。

fetchall():从结果集中返回所有数据。

2.4 数据库的CRUD操作示例

@2.4.1 数据插入(Creat)

 数据插入操作的SQL语句INSERT,代码如下:

import sqlite3  # 导入sqlite3模块
import os

# 数据库文件路径
db_path = r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db'

# 检查文件是否存在
if not os.path.exists(db_path):
    print(f"数据库文件 {db_path} 不存在!")
i_name = input('请输入姓名:')  # 获取用户输入的姓名
i_sex = input('请输入性别(1表示男,0表示女):')  # 获取用户输入的性别
i_birthday = input('请输入生日(YYYYMMDD):')  # 获取用户输入的生日

try:
    # 连接到SQLite数据库
    con = sqlite3.connect(r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db')

    # 创建一个Cursor对象,用于执行SQL命令
    cursor = con.cursor()

    # 执行SQL查询操作
    sql = 'INSERT INTO  student(s_name, s_sex, s_birthday) VALUES (?, ?, ?)'
    cursor.execute(sql, [i_name, i_sex, i_birthday])  # 执行SQL命令,参数放到序列或元组中

    # 提取数据库事务
    con.commit()
    print('插入成功!')

except sqlite3.Error as e:
    print('插入数据失败:{}'.format(e))

    # 回滚数据库事务
    con.rollback()

finally:
    # 关闭游标
    if cursor:
        cursor.close()

    # 关闭数据库连接
    if con:
        con.close()

@2.4.2 数据查询(Read)

SQL查询语句是SELECT,根据是否带有WHERE子句,分为:无条件查询和有条件查询

***********无条件查询,没有WHERE子句**********,代码如下:

import sqlite3  # 导入sqlite3模块
import os

# 数据库文件路径
db_path = r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db'

# 检查文件是否存在
if not os.path.exists(db_path):
    print(f"数据库文件 {db_path} 不存在!")

try:
    # 连接到SQLite数据库
    con = sqlite3.connect(r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db')

    # 创建一个Cursor对象,用于执行SQL命令
    cursor = con.cursor()

    # 执行SQL查询操作
    sql = 'SELECT s_id, s_name, s_sex, s_birthday FROM student'
    cursor.execute(sql)  # 执行SQL命令

    # 提取结果集
    result_set = cursor.fetchall()
    for row in result_set:
        print('学号:{0} - 姓名:{1} - 性别:{2} - 生日:{3}'.format(row[0], row[1], row[2], row[3]))

except sqlite3.Error as e:
    print('数据库查询发生错误:{}'.format(e))

finally:
    # 关闭游标
    if cursor:
        cursor.close()

    # 关闭数据库连接
    if con:
        con.close()

 *************有条件查询**************有WHERE子句,WHERE子句是查询条件,

代码如下:

# 有条件查询,有WHERE子句,WHERE自己是查询条件
import sqlite3  # 导入sqlite3模块
import os

# 数据库文件路径
db_path = r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db'

# 检查文件是否存在
if not os.path.exists(db_path):
    print(f"数据库文件 {db_path} 不存在!")

istr = input('请输入生日(YYYYMMDD):')  # 获取用户输入的生日

try:
    # 连接到SQLite数据库
    con = sqlite3.connect(r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db')

    # 创建一个Cursor对象,用于执行SQL命令
    cursor = con.cursor()

    # 执行SQL查询操作
    sql = 'SELECT s_id, s_name, s_sex, s_birthday FROM student WHERE s_birthday < ?'  # 查询学生信息
    cursor.execute(sql, [istr])  # 执行SQL命令,参数放到序列或元组中

    # 提取结果集
    result_set = cursor.fetchall()
    for row in result_set:
        print('学号:{0} - 姓名:{1} - 性别:{2} - 生日:{3}'.format(row[0], row[1], row[2], row[3]))

except sqlite3.Error as e:
    print('数据库查询发生错误:{}'.format(e))

finally:
    # 关闭游标
    if cursor:
        cursor.close()

    # 关闭数据库连接
    if con:
        con.close()

@2.4.3 数据更新(Update)

数据更新操作的SQL语句是UPDATE。示例如下:

import sqlite3  # 导入sqlite3模块
import os

# 数据库文件路径
db_path = r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db'

# 检查文件是否存在
if not os.path.exists(db_path):
    print(f"数据库文件 {db_path} 不存在!")
i_id = input('请输入学号:')  # 获取用户输入的学号
i_name = input('请输入姓名:')  # 获取用户输入的姓名
i_sex = input('请输入性别(1表示男,0表示女):')  # 获取用户输入的性别
i_birthday = input('请输入生日(YYYYMMDD):')  # 获取用户输入的生日

try:
    # 连接到SQLite数据库
    con = sqlite3.connect(r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db')

    # 创建一个Cursor对象,用于执行SQL命令
    cursor = con.cursor()

    # 执行SQL查询操作
    sql = 'UPDATE  student SET s_name=?, s_sex=?, s_birthday=? WHERE s_id=?'
    cursor.execute(sql, [i_name, i_sex, i_birthday, i_id])  # 执行SQL命令,参数放到序列或元组中

    # 提取数据库事务
    con.commit()
    print('更新数据库成功')

except sqlite3.Error as e:
    print('更新数据库失败:{}'.format(e))

    # 回滚数据库事务
    con.rollback()

finally:
    # 关闭游标
    if cursor:
        cursor.close()

    # 关闭数据库连接
    if con:
        con.close()

@2.4.4数据删除(Delete)

数据删除操作SQL语句是DELETE。示例如下:

import sqlite3  # 导入sqlite3模块
import os

# 数据库文件路径
db_path = r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db'

# 检查文件是否存在
if not os.path.exists(db_path):
    print(f"数据库文件 {db_path} 不存在!")
i_id = input('请输入要删除学生的学号:')  # 获取学号

try:
    # 连接到SQLite数据库
    con = sqlite3.connect(r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db')

    # 创建一个Cursor对象,用于执行SQL命令
    cursor = con.cursor()

    # 执行SQL查询操作
    sql = 'DELETE  FROM student  WHERE s_id=?'
    cursor.execute(sql, [i_id])  # 执行SQL命令,参数放到序列或元组中

    # 提取数据库事务
    con.commit()
    print('删除数据成功')

except sqlite3.Error as e:
    print('删除数据失败:{}'.format(e))

    # 回滚数据库事务
    con.rollback()

finally:
    # 关闭游标
    if cursor:
        cursor.close()

    # 关闭数据库连接
    if con:
        con.close()

可以看到下图s_id=5的学生张三被删除 

2.5 防止 SQL注入攻击

示例如下:

import sqlite3  # 导入sqlite3模块
import os

# 数据库文件路径
db_path = r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db'

# 检查文件是否存在
if not os.path.exists(db_path):
    print(f"数据库文件 {db_path} 不存在!")

istr = input('请输入生日(YYYYMMDD):')  # 获取用户输入的生日

try:
    # 连接到SQLite数据库
    con = sqlite3.connect(r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db')

    # 创建一个Cursor对象,用于执行SQL命令
    cursor = con.cursor()

    # 执行SQL查询操作
#    sql = 'SELECT s_id, s_name, s_sex, s_birthday FROM student WHERE s_birthday < ?'  # 查询学生信息
#    cursor.execute(sql, [istr])  # 执行SQL命令,参数放到序列或元组中
    sql = 'SELECT s_id, s_name, s_sex, s_birthday FROM student WHERE s_birthday < ' + istr  # 查询学生信息,这种方式容易造成,SQL注入攻击
    cursor.execute(sql)  # 执行SQL命令,参数放到序列或元组中

    # 提取结果集
    result_set = cursor.fetchall()
    for row in result_set:
        print('学号:{0} - 姓名:{1} - 性别:{2} - 生日:{3}'.format(row[0], row[1], row[2], row[3]))

except sqlite3.Error as e:
    print('数据库查询发生错误:{}'.format(e))

finally:
    # 关闭游标
    if cursor:
        cursor.close()

    # 关闭数据库连接
    if con:
        con.close()

图一是查询20050101之前的

图二SQL注入是查询所有数据,如果是删除,损失可想而知!!!! 

相关推荐

  1. LeetCode 九天

    2024-04-26 01:16:02       56 阅读
  2. Python学习笔记九天(OpenCV轨迹栏)

    2024-04-26 01:16:02       36 阅读
  3. 网络工程师----九天

    2024-04-26 01:16:02       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-26 01:16:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-26 01:16:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-04-26 01:16:02       58 阅读
  4. Python语言-面向对象

    2024-04-26 01:16:02       69 阅读

热门阅读

  1. 2024年GPLT团体程序设计竞赛题解(无L3-3)

    2024-04-26 01:16:02       24 阅读
  2. Day6: 5道C++ 面向对象高频题整理

    2024-04-26 01:16:02       29 阅读
  3. optim.lr_scheduler.StepLR学习

    2024-04-26 01:16:02       30 阅读
  4. 洛谷 P5960 [模板] 差分约束 题解 SPFA

    2024-04-26 01:16:02       31 阅读
  5. Thread 类的基本用法

    2024-04-26 01:16:02       23 阅读
  6. 流程图画图规范

    2024-04-26 01:16:02       26 阅读
  7. 浅谈Spring中的事务【Transactional】

    2024-04-26 01:16:02       28 阅读
  8. 【Python】使用Python连接ClickHouse进行批量数据写入

    2024-04-26 01:16:02       25 阅读
  9. nlp(6)--构建找规律模型任务

    2024-04-26 01:16:02       26 阅读
  10. 练习-字符串逆序统计

    2024-04-26 01:16:02       31 阅读
  11. 学习redis知识点

    2024-04-26 01:16:02       29 阅读