Python进阶系列
Python进阶-网络编程-01
Python进阶-网络编程-02
Python进阶-网络编程-03
Python进阶-多任务编程-01
Python进阶-多任务编程-02
Python进阶-多任务编程-03
Python进阶-正则表达式
Python进阶-数据库编程-01
Python进阶-数据库编程-02
Python进阶-数据库编程-03
Python进阶-数据库编程-04
Python进阶-数据拷贝问题
Python进阶-模块导入问题
Python进阶-miniWeb框架
文章目录
13.1. 索引
-
索引作用:提升查询效率
-
索引的使用:
-
查看索引
show index from 表名
-
创建索引
create index 索引名 on 表名(表中的字段名(字段长度))
-
如果字段是字符串类型,需要指定长度
-
如果字段不是字符串类型,可以不指定长度
-
-
删除索引
drop index 索引名 on 表名;
-
-
插入10万条数据到数据库中
- pymysql 操作步聚:
- 导入模块
- 创建连接对象
- 创建游标对象
- for循环,插入10万条数据
- 提交数据
- 关闭游标
- 关闭连接
- pymysql 操作步聚:
-
验证索引效果
- 开启检测 set profiling = 1;
- 执行sql
- 查看每一个sql执行的时间 show profiles;
- 添加索引
- 执行sql
- 查看执行效率 show profiles;
-
代码实例:
# 1.导入模块 import pymysql # 2.创建连接对象 conn = pymysql.connect(host="localhost",user="root",password="107314",database="python_index_db") # 3.创建游标对象 cur = conn.cursor() try: # 4.for循环,插入10万条数据 for i in range(100000): cur.execute("insert into test_index(title) values('ha-%d')" % i) # 5.提交数据 conn.commit() except Exception as e: print(e) conn.rollback() finally: # 6.关闭游标 cur.close() # 7.关闭连接 conn.close()
13.2. 用户管理(一)
-
创建用户
create user '用户名'@'主机' identified by '密码'
-
授权
权限:
create
drop
select
insert
update
所有权限:
all privileges
;grant 权限 on 数据库.表 to '用户名'@'主机';
-
查询权限
show grants for '用户名'@'主机名'
-
刷新权限
flush privileges;
13.3. 用户管理(二)
-
修改用户权限
grant 权限 on 数据表.表 to '用户名'@'主机' with grant option;
-
修改用户密码
- 知道密码,改新密码
alter user '用户名'@'主机' identified by '新密码';
-
忘记密码,重置密码
- 停止服务,设置跳过正常验证,设置密码为空
- 设置正常验证模式,重启服务,用空密码登录,改成新密码
-
删除用户
drop user '用户名'@'主机';
13.4. 爬虫实战:爬取数据并保存到数据库中
-
思路:
-
定义专门的函数,负责保存数据
add_film()
1) 定义SQL语句,准备插入数据
2) 执行SQL语句
-
定义专门函数,负责检测数据库中是否存在相同的数据
film_exist()
1)定义sql 根据影片名称和地址 查询
2)执行查询,并获取查询的记录数
3)如果获取的记录数>0 return True
4) 如果获取的记录数=0 return False
-
创建连接对象
(全局)
-
创建游标对象
(全局)
-
关闭操作
-
-
简单爬虫-数据库版
import urllib.request import re import pymysql def main(): # 获取电影的影片名称和下载地址字典 films_dict = get_movie_links() # 把字典遍历输出 # films_dict.items()把字典转换为可遍历的元组 for film_name,film_link in films_dict.items(): if film_exist(film_name,film_link): print("保存失败!影片%s" % film_name) continue # 调用add_film方法添加数据 add_film(film_name,film_link) def add_film(film_name,film_link): """保存影片到数据库中""" # 定义sql 准备插入数据 底层防注入 sql = "insert into movie_link values (null,%s,%s)" # 执行SQL语句 ret = cur.execute(sql,[film_name,film_link]) if ret: print("保存成功!影片[%s]" % film_name) def film_exist(film_name,film_link): """用于检测数据是否已经存在""" sql = "select id from movie_link where film_name = %s and film_link=%s limit 1" ret = cur.execute(sql, [film_name, film_link]) if ret: return True else: return False def get_movie_links(): """获取列表页影片信息""" # 1.定义列表页的地址 https://www.ygdy8.net/html/gndy/dyzz/index.html file_list_url = "https://www.ygdy8.net/html/gndy/dyzz/list_23_1.html" # 2.打开url地址,获取数据 response_list = urllib.request.urlopen(file_list_url) # 通过read()读取网络资源数据 response_list_data = response_list.read() # 3.解码获取到的数据 response_list_text = response_list_data.decode("GBK") # 4.使用正则得到所有的影片内容页地址 # print(response_list_text) # 4.1 使用findall() 根据正则查找所用影片对应的内容页地址 url_list = re.findall(r"<a href=\"(.*)\" class=\"ulink\">(.*)</a>",response_list_text) # 4.2 保存地址,定义一个字典用于保存影片信息 films_dict = {} i=1 # 4.3 循环遍历 url_list for content_url,file_name in url_list: content_url = "https://www.ygdy8.net" + content_url # print("影片名称:%s, 内容页地址:%s" % (file_name,content_url)) # 4.4 打开内容页地址 response_content = urllib.request.urlopen(content_url) # 4.5 接收内容页数据 # 4.6 读取网络资源 response_content_data = response_content.read() # 4.7 解码得到内容页的文本内容 response_content_text = response_content_data.decode("GBK") # 4.8 取出下载地址 # print(response_content_text) result = re.search(r"magnet:\?xt=urn:btih:(.*)fannounce",response_content_text) # print("下载地址%d:" % i,result.group()) # 字典 # {"xxx":"XXX地址"} films_dict[file_name] = result.group() print("已经获取%d条信息" % i) i += 1 return films_dict if __name__ == '__main__': # 3.创建连接对象 conn = pymysql.connect(host="localhost",user="root",password="107314",database="movie_db") # 4.创建游标对象 cur = conn.cursor() # 爬取数据 main() conn.commit() # 5.关闭操作 cur.close() conn.close()
13.5. 爬虫实战:展示电影数据到网页中
-
思路:
-
把web服务器返回固定内容 代码拷贝过来
-
把原本固定的内容变为从数据库动态读取
1)导入
pymusql
模块 2)连接数据库,并且查询影片的所有信息
3)遍历查询结果集,拼接响应的主体
-
-
简单爬虫-展示影片信息
import socket import pymysql def request_handler(new_client_socket,ip_port): """接收信息,做出响应""" # 7、接收客户端刘觉器发送的请求协议 request_data = new_client_socket.recv(1024) # 8、判断协议是否为空 if not request_data: print("%s客户端已经下线" % str(ip_port)) new_client_socket.close() return # 9、拼接响应的报文 # 响应行 response_line = "HTTP/1.1 200 OK\r\n" # 响应头 response_header = "Server:Python20WS/2.1\r\n" response_header += "Content-type:text/html;charset=utf-8\r\n" # 响应空行 response_blank = "\r\n" # 响应主体 response_body = "" # 1)导入pymusql模块 # 2)连接数据库,并且查询影片的所有信息 conn = pymysql.connect(host="localhost",user="root",password="107314",database="movie_db") cur = conn.cursor() # 3)遍历查询结果集,拼接响应的主体 cur.execute("select * from movie_link order by id desc ") # 返回元组值 result_list = cur.fetchall() for row in result_list: response_body += "%d.%s 下载地址:[<a href='%s'>%s</a>] <br>" % (row[0],row[1],row[2],row[2]) cur.close() conn.close() response_data = response_line + response_header + response_blank + response_body # 10、发送响应报文 new_client_socket.send(response_data.encode()) # 11.关闭当前连接 new_client_socket.close() def main(): # 1、导入模块 # 2、创建套接字 tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 3、设置地址重用 tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True) # 4、绑定端口 tcp_server_socket.bind(("",8080)) # 5、设置监听,让套接字由主动变为被动接收 tcp_server_socket.listen(128) # 6、接受客户端连接定义函数request handler() while True: new_client_socket,ip_port = tcp_server_socket.accept() # 调用函数处理请求并且响应 request_handler(new_client_socket,ip_port) # 11、关闭操作 tcp_server_socket.close() if __name__ == '__main__': main()
13.6. 闭包的概念及基本使用
-
概念:在一个外函数中定义了一个内函数,内函数里用了外函数的临时变量,并且外函数的返回值是内函数的引用,这就构成了一个闭包。
-
闭包构成的条件:
- 存在函数的嵌套关系
- 内层函数引用了外层函数的临时变量
- 外层函数返回内层函数
-
代码实例:
def function_out(num): print("function_out num =",num) def function_in(num_in): print("function_in num=",num) print("function_in num_in=",num_in) return function_in ret = function_out(100) ret(88)
13.7. 闭包中变量问题
-
内层定义了和外层同名的变量
内层优先使用内层定义的变量,即使定义变量的代码在内层的最后面
-
解决办法:当内层存在和外层同名变量,而且内层需要使用外层定义的变量,此时应该使用nonlocal 关键字进行约束
-
代码实例:
def function_out(num): def function_in(): # 造成错误的原因:编译器认为内层函数已经定义了num变量,优先使用内层 # 如果在内层定义了和外层同名的变量,而且需要使用外层的变量 # nonlocal不使用内部的变量,使用外层的变量 nonlocal num print("num=",num) num = 88 print(num) return function_in ret = function_out(10) ret()
13.8. 装饰器入门
-
定义: 装饰器本质上是一个Python函数(其实就是闭包),它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。装饰器用于有以下场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。
-
装饰器的使用:
- 存在闭包(用于拓展新的功能)
- 需要装饰的函数
-
代码实例1:
def function_out(func): def function_in(): print("开始验证") func() return function_in @function_out def login(): print("开始登录") login()
-
代码实例2:
import time import threading # 为函数添加一个统计运行时长的装饰器 def how_much_time(func): def inner(): t_start = time.time() func() t_end = time.time() print("一共花费了{0}秒时间".format(t_end - t_start, )) return inner # 将增加的新功能代码以及被装饰函数运行代码func()一同打包返回, # 返回的是一个内部函数,这个被返回的函数就是装饰器 def sleep_5s(): time.sleep(5) print("%d秒结束了" % (5,)) def sleep_6s(): time.sleep(6) print("%d秒结束了" % (6,)) sleep_5s = how_much_time(sleep_5s) # 因为sleep_5s函数的功能就是睡5秒钟,虽然增加了统计运行时间的功能, # 但是他本身功能没变(还是睡5秒钟),所以仍然用原来函数名接收增加功能了的自己 sleep_6s = how_much_time(sleep_6s) t1 = threading.Thread(target=sleep_5s) t2 = threading.Thread(target=sleep_6s) t1.start() t2.start()
-
代码实例3:
@mylog @how_much_time def sleep_5s(): time.sleep(5) print("%d秒结束了" % (5,))
13.9. 装饰有参数的函数
-
代码实例:
def function_out(func): def function_in(num): print("开始验证 num =",num) func(num) return function_in # login = function_out(login) @function_out def login(num): print("开始登录 num = ",num) login(10)
13.10. 装饰有可变参数的装饰器
-
代码实例:
def function_out(func): def function_in(*args,**kwargs): print("function_in login:args=", args) print("function_in login:kwargs=", kwargs) func(*args,**kwargs) return function_in @function_out def login(*args,**kwargs): print("login:args=",args) print("login:kwargs=",kwargs) login(10,a=10)
13.11. 装饰有返回值的函数
-
步骤
- 待装饰的函数必须有返回值(return)
- 闭包的内层函数
func(*args , **kwargs)
改为return func(*args , **kwargs)
-
代码实例:
def function_out(func): def function_in(num): print("开始验证") return func(num) return function_in @function_out # login = function_out(login) def login(num): print("开始登录") return num + 10 result = login(8) print(result)
13.12. 通用版装饰器
-
代码实例
def function_out(func): def function_in(*args,**kwargs): print("function_in login:args=", args) print("function_in login:kwargs=", kwargs) return func(*args,**kwargs) return function_in @function_out def login(*args,**kwargs): print("login:args=",args) print("login:kwargs=",kwargs) return 10 result = login(10,a=10) print(result)