第六周内容回顾
文章目录
1、正则表达式
*正则表达式不属于任何一门编程语言,主要作用就是用于数据的查找与筛选
正则表达式概念
正则比倒是本质就是使用一些符号组合产生一些特殊的含义,然后去字符串中筛选出符合条件的数据
1.1、正则表达式之特殊符号
字符 | 功能 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配 字母 下划线 数字 |
\W (大写W) | 匹配 字母或数字 或下划线 |
\d | 匹配数字 |
[] | 字符组 |
^ | 匹配字符串开通 |
$ | 匹配字符串结尾 |
[^] | 匹配 除该字符组以外的字符 |
^a$ | 匹配精确的字符组 |
``a | b`` |
() | 用于正则表达式 中 的分组 |
1.2、正则表达式之字符组
字符组 | 功能 |
---|---|
[a-z] | 匹配小写字母 a到z之间的字母 |
[A-Z] | 匹配大写字母 A到Z之间的字母 |
[0-9] | 匹配 0到9的任意数字 |
1.3、正则表达式 之量词
字符 | 功能 |
---|---|
* | 重复零次或多次 |
+ | 重复一次或多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,y} | 重复n次至y次 |
1.4、正则表达式之贪婪匹配与非贪婪匹配
1.4.1、贪婪匹配
所有量词默认都是贪婪匹配,但是如果在量词后面跟一个问好,那么就会变成非贪婪匹配
- 以后我们在使用贪婪匹配或非贪婪匹配的时候一般都是用
.*
或.*?
并且在哪结束可以由上诉符号左边两边添加表达式决定
贪婪匹配示例
#文本
<script>alert(123)</script>
#正则表达式
<.*>
>>>>>>>>>>>>>>>>>匹配结果
['<script>alert(123)</script>']
1.4.2、非贪婪匹配
非贪婪匹配示例
#匹配文本
<script>alert(123)</script>
#正则表达式
<.*>
>>>>>>>>>>>>>>>>>匹配结果
['<script>', '</script>']
1.4正则表达式取消转义
正则表达式中,有时候斜杠与字母组合存在特殊意义,通过在斜杠前面加斜杠就可以转义
在多个斜杠情况下 可以通过再多加同等数量的斜杠来取消转义
表达式 | 取消转义后的表达式 |
---|---|
\n | \\n |
\\n | \\\\n |
python 解释器中
在python中可以通过直接引号前面加r
的方式来取消转义
正则表达式 | 取消转义后的表达式 |
---|---|
'\n' | r'\n' |
'\\n' | r'\\n' |
2、re模块
在python解释器中 如果想要使用正则表达式,re模块是选择之一
通过正则表达式筛选除文本中所有符合条件的数据
re.findall
import re
res=re.findall('a','jason oscar aaa')
print(res)
>>>>>>>>>>>>>>>>>>>>>>
['a', 'a', 'a', 'a', 'a']
通过正则表达式筛选除文本中所有符合条件的数据,将其处理成迭代器对象,用于节省空间
re.finditer
import re
res=re.finditer('a','jason oscar aaa')
print(res)
>>>>>>>>>>>>>>>>>>>>>>>>>>
<callable_iterator object at 0x000002514D4F5C70>
通过正则表达式匹配文本,当匹配到一个符合条件的内容就结束匹配
re.search
import re
res=re.search('a','jason oscar aaa')
print(res)
print(res.group())
>>>>>>>>>>>>>>>>>>>>>>>>>
<re.Match object; span=(1, 2), match='a'>
a
通过正则表达式 从头开始匹配,如果开头匹配不管是否符合都结束
re.match
import re
res=re.match('a','jason oscar aaa')
print(res)
None
能够提前 准备好正则表达式,之后 可以反复使用,减少代码冗余
re.compile
import re
obj=re.compile('a')
print(re.findall(obj,'ahfjklhala'))
>>>>>>>>>>>>>>>>>>>>>>>>>>
['a', 'a', 'a']
2.1、re模块 补充说明
2.1.1、分组
针对分组的正则表达式匹配的到的结果 优先展示
import re
res=re.findall('a(b)c','abc,abc,abc,abc')
print(res)
>>>>>>>>>>>>>>>>>>>>
['b', 'b', 'b', 'b']
取消分组的优先展示
import re
res=re.findall('a(?:b)c','abcabacabc')
print(res)
>>>>>>>>>>>>>>>>>>>>>>>>>
['abc', 'abc', 'abc']
2.1.2、别名
在
search
中 可以对优先匹配的起别名 后续可以利用该名 直接匹配文本中第一个匹配项
import re
res=re.search('a(?P<id>b)(?P<name>c)','abcabcabcabc')
print(res.group())
print(res.group(1))
print(res.group('id'))
print(res.group('name'))
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
abc
b
b
c
3、网络爬虫简介
什么是互联网?
- 将全世界计算机接到一起组成的网络
互联往发明的每亩地是什么?
- 将接入互联网的计算机上面的数据彼此共享
上网的本质是什么?
- 基于互联网访问别人的计算机上面的资源(有些计算机存在的意义就是让别人访问,这种类型的而计算机,我们也称之为服务器)
网络爬虫的本质
- 模拟计算机游览器朝目标网址发送请求返回目标网页数据并删选,只要是游览器可以访问到的数据,网络爬虫理论上都可以爬取
3.1、requests模块
向网页发送网络请求,获取网页中源码
requests.get
import requests
res=requests .get('')
print(res.text) #转化为解码之后的数据
with open(r'lj.html','wb')as lj_w:
lj_w,write(res.content) #通过content转为bytes类型数据,然后写入html文件中
4、第三方模块的下载
第三方模块,必须先下载后导入使用
python下载第三方模块需要借助于pip工具
python解释器 终端下载模块 命令
pip3.7 install 模块名
下载模块指定版本:
pip3.7 install 模块名==版本号
pip工具默认是从国外仓库地址下载模块、在国内 速度可能不快
我们可以切换下载的地址(源地址)
清华大学 :https://pypi.tuna.tsinghua.edu.cn/simple/
阿里云:http://mirrors.aliyun.com/pypi/simple/
中国科学技术大学 :http://pypi.mirrors.ustc.edu.cn/simple/
华中科技大学:http://pypi.hustunique.com/
豆瓣源:http://pypi.douban.com/simple/
腾讯源:http://mirrors.cloud.tencent.com/pypi/simple
华为镜像源:https://repo.huaweicloud.com/repository/pypi/simple/
临时修改下载地址
pip 3.7 install 模块名 -i 源地址
pycharm提供第三方模块的下载快捷方式
也可以直接修改 python解释器源文件
在终端下载模块可能遇到的报错
-
pip 工具版本过低 直接拷贝提示信息里面的更新命令即可
-
python38 -m pip install --upgrade pip
-
-
网络波动 关键字
read tinme out
只需要 重新下载几次即可 或者 切换一个网络稳定一点的
-
有些模块 在下载使用 之前需要提前配置指定的环境
5、openpysl 模块
主要用于操作excel表格 也是pands底层操作表格的模块
在python中能够操作excel表格的模块由很多 openpys属于近几年比较流行的模块(openpyx 针对03版本之前的excel文件兼容性不好)
xlwt、xird 也可以操作excel表格,兼容所有版本的excel文件 但是使用方法没有ooenpyxl简单
excel版本问腿
03版本之前 excel’文件的后缀名.xls
03版本之后 excel文件的后缀名.xlsx
如果是苹果电脑 excel文件的后缀.csv
5.1、openpyxl 对excel文件的基本操作
5.1.1写数据
创建excel文件、创建工作簿
from openpyxl import Workbook
wb=Workbook()
wb1=wb.create_sheet('某某班成绩') #创建工作簿
wb1.title='6年纪2班成绩' # 修改工作簿名字
wb.save(r'aa.xlsx') #保存文件
通过 列 行 编号 添加内容
from openpyxl import Workbook
# 按列 和宽 添加 内容
wb1 ['A1']=姓名
wb1['B1']=学号
wb1['C1']=语文成绩
wb1['D1']=数学成绩
wb.sace(r'aa.xlsx') #
通过列表 批量添加
from openpyxl import Workbook
wb1.append(['小明','5','92','95'])
wb.save(r'aa.xlsx)
5.1.2、读数据
查看excel中所有 工作簿的信息
from openpyxl import Workbook
wb1=wb=['6年纪2班成绩'] #查看指定 工作簿的内容
print(wb1.max_row) #查看该表内容的列数
print(wb1.max_column) # 查看该表内容的行数
print(wb1['A1'].value) # 查看该表 字符组中对应的内容
print(wb1.cell(row=2,column=2).value) # 获取第二列 第二行 的内容
for j in wb1.columns:
print([i.value for i in j])
openpyxl
并不擅长读数据,所以有了一些模块优化了它的读取方式,也就是pandas
模块
6、random 随机模块
防御0到1之间随机的小数
random
import random
print(random.random())
返回两个参数之间的随机整数(左右包含)
randit
import random
print(random.randint(1,6))
随机从容器中 抽取一个元素
choice
import random
print(random.choice(['asd','ad',23,65]))
随机抽样 且可以自定义抽取个数
sample
import random
print(random.sample(['花花','红红','江江',123]))
打乱排序
shuffle
l1=[2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A', '大王', '小王']
random.shuffle(l1)
print(l1)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
[8, 'J', 5, 3, 'K', 2, 6, 10, 7, 4, 'A', 'Q', 9, '小王', '大王']
7、hashlib 加密模块
加密是指将人能看的懂得明文数据经过处理之后变成人看不懂得密文数据的过程
加密的作用:
可以大大降低一些铭感数据的泄露
判断该数据是否已经加密
一般情况下 如果一串没有规则的数字字母符号的组合一般哦都是经过加密之后的结果
加密的算法
就是对明文数据采用加密策略,不同的加密算法复杂度不一样,得出的结果长短也不一样,通常情况下同段明文 加密之后的结果越长,说明采用的加密算法越复杂
常见的加密算法
md5,sha
系列,hmac base64
加密实例
import hashlib
md5=hashlib.md5()
md5.update(bytes('123','utf'))
res=md5.hexdigest()
print(res)
7.1加密模块扩展说明
明文数据加密过后不能再对数据进行反解密
我们见过的反解密,并非流程上的反解密。是别人通过存储明文数据对应的关系,通过比对密文数据,来映射出明文数据
只要明文数据是一样的,那么采用相同的算法得出的密文肯定一样
import hashlib
md5 = hashlib.md5() # 选择md5加密算法作为数据的加密策略
# md5.update(b'123')
# md5.update(b'123') # 加密两次123
# res = md5.hexdigest()
# print(res) #4297f44b13955235245b2497399d7a93
md5.update(b'123123')
res2=md5.hexdigest()
print(res2)
7.1.1、加盐处理
为了防止 密文与对应的明文已经被人存储,所以我们可以通过加密时添加一些干扰项,来防止密码重复
password = input('password>>>:').strip()
md5.update('公司设置的盐(干扰项)'.encode('utf8'))
md5.update(password.encode('utf8'))
res = md5.hexdigest()
7.1.2、动态加盐
动态加盐 就是将加盐处理的干扰项每次都不一样
例如 将干扰项设置为当时的时间,或者每个用户的用户名截取一段
7.2、加密的应用场景
场景一:用户密码加密
注册时直接存储密文
登录时密码比对 也是比对的密文
场景二“:文件安全性校验
正规的软件程序写完之后 会做一个内容加密,网址提供然间 文件记忆该文件内容对应的密文,用户下载完后不直接运行,而是对下载的内容做加密,然后比对量词密文是否一致,表示文件没有被改,如果不一致,则表示该程序被更改过,可能被植入病毒
-
大文件加密优化
当程序文件过大时,直接全部加密太慢时,可以对一部分加密,例如每隔500M读取30bytes
8、subprocess 模块
主要作用
模拟计算机cmd命令窗口
import subprocess
cmd = inpurt('请输入您的指令>>>').strip()
sub = subprocess.Popen(cmd,shell=True,
shtdoy=subprocess.PIPE
stderr=subprocess.PIPE)
#stdout 执行命令之后正确的返回结果
print(sub.stdout.red().decode('gbk'))
#stderr执行命令 报错之后返回的结果
print(sub.stderr.red().decode('gbk'))
9、日志模块
日志模块 一般使用可以直接cv
日志的作用
为了记入事物发生的事实(史馆)
9.1、日志等级
import logging
logging.debug('事件') #等级 10
logging.info('事件') #等级20
logging.warning('事件') # 等级30 #一般默认从warning级别开始记录日志
logging.error('事件') # 等级40
logging.critical('事件') #等级50
9.2、日志模块主要组成
import logging
# 1.logger对象:产生日志 (无包装的产品)
logger = logging.getLogger('转账记录')
# 2.filter对象:过滤日志 (剔除不良品)
# 针对过滤功能完全可以不看 因为handler自带了基本的过滤操作
# 3.handler对象:控制日志的输出位置(文件、终端...) (产品分类)
hd1 = logging.FileHandler('a1.log',encoding='utf-8') # 输出到文件中
hd2 = logging.FileHandler('a2.log',encoding='utf-8') # 输出到文件中
hd3 = logging.StreamHandler() # 输出到终端
# 4.format对象:控制日志的格式 (包装)
fm1 = logging.Formatter(
fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
)
fm2 = logging.Formatter(
fmt='%(asctime)s - %(name)s: %(message)s',
datefmt='%Y-%m-%d',
)
# 5.给logger对象绑定handler对象
logger.addHandler(hd1)
logger.addHandler(hd2)
logger.addHandler(hd3)
# 6.给handler绑定formmate对象
hd1.setFormatter(fm1)
hd2.setFormatter(fm2)
hd3.setFormatter(fm1)
# 7.设置日志等级
logger.setLevel(10) # debug
# 8.记录日志
logger.debug('写了半天 好累啊 好热啊!!!')
9.4、配置字典
import logging
import logging.config
# 定义日志输出格式 开始
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
# 自定义文件路径
logfile_path = 'a3.log'
# log配置字典
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format
},
'simple': {
'format': simple_format
},
},
'filters': {}, # 过滤日志
'handlers': {
#打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
#打印到文件的日志,收集info及以上的日志
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
'formatter': 'standard',
'filename': logfile_path, # 日志文件
'maxBytes': 1024*1024*5, # 日志大小 5M
'backupCount': 5,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
},
'loggers': {
#logging.getLogger(__name__)拿到的logger配置
'': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
}, # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
# '购物车记录': {
# 'handlers': ['default','console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
# 'level': 'WARNING',
# 'propagate': True, # 向上(更高level的logger)传递
# }, # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
},
}
logging.config.dictConfig(LOGGING_DIC) # 自动加载字典中的配置
logger1 = logging.getLogger('登录记录')
logger1.debug('jason 登录成功')
9.5、项目中使用
字典数据是日志模块固定的配置 写完一次之后几乎都不需要改动,所以它属于配置文件
- 配置文件中变量名推荐全大写
#将日志使用封装为函数,并将最后一步 通过返回值 返回后在需要用的时候编写
def get_logger(data):
logging.config.dictConfig(settings.LOGGING_DIC) # 自动加载字典中的配置
logger1 = logging.getLogger(data)
# logger1.debug(f'{username}注册成功') # 这里让用户自己写更好
return logger1
get_logger('注册记录')。debug('新用户kk注册成功')