- Day29常用模块拓展
- 1、openpyxl模块读数据
- 1.1、pandas 模块
- 1.2、实战
- 2、random 随机模块
- 2.1、随机模块应用于验证码
- 3、hashlib 加密模块
- 3.1、加密模块扩展说明
- 3.1.2、加密应用场景
- 4、subprocess 模块
- 5、日志模块
- 5.1、日志模块组成部分
- 5.2、实战应用
- 作业
查看 excel 中所有工作簿
wb = load_workbook(r'hn.xlsx',data_only=True) print(wb.sheetnames) # 查看excel 文件中的所有工作簿名称 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ['Sheet', '红牛分公司信息']
查看工作指定工作簿中的信息
wb1=wb['红牛分公司信息'] #定义查看该表的变量名 print(wb1.max_row) #查看 该表中内容的列数 print(wb1.max_column) #查看 该表中 内容的行数 print(wb1['A1'].value) #获取 A1对应格子中的数据 print(wb1.cell(row=2,column=2).value) #获取 第二列第二行的数据 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 41 4 红牛公司名 杭州市上城区庆春路29号远洋大厦11楼A座
1.1、pandas 模块openpyxl并不擅长读数据,所以有了一些模块优化了它的读取的方式
就是 pandas 模块
写入数据
import pandas
#将写入的数据定义为字典,每个键值对为一列,以键为 列的开头,将值中的表格 里的数据 写入当列
d={
'公司名称': ['红牛', '黑牛', '黄牛', '铁牛'],
'公司地址': ['上海', '深圳', '杭州', '东京'],
'公司电话': [123142, 124142, 13634, 1524348],
}
info=pandas.DataFrame(d) #将信息 写入工作簿
info.to_excel(r'a.xlsx') #保存生成 excel文件
1.2、实战
# res=requests.get(f'https://hz.fang.lianjia.com/loupan/fuyang/pg2/')
# with open(r'fy.html','wb')as fy_w:
# fy_w.write(res.content)
with open(r'fy.html', 'r', encoding='utf')as fy_r:
res = fy_r.read()
# print(res)
house_name = re.findall(
'',
res)
# house_name=re.findall('')
house_address = re.findall('(.*?)', res)
house_m2 = re.findall('建面 (.*?)㎡', res)
house_money = re.findall('(.*?)', res)
house_money_all = re.findall('(.*?)', res)
print(house_name)
print(house_address)
print(house_m2)
# print(house_money)
# print(house_money_all)
import pandas
house_money.pop(10)
house_money.pop(10)
house_money.pop(10)
house_money_all.pop(10)
print(house_money)
print(house_money_all)
fuyang_house = {'小区名': house_name,
'小区地址': house_address,
'面积': house_m2,
'每平单价': house_money,
'总价':house_money_all}
info = pandas.DataFrame(fuyang_house)
info.to_excel(r'fy.xlsx')
2、random 随机模块
返回0到1之间随机的小数
random
import random print(random.random()) >>>>>>>>>>>>>>>>>>>>>>>> 0.1534858207095654
返回两个参数之间的随机整数(左右包含)
randint(1,6)
import random print(random.randint(1,6)) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 5
随机从容器中中抽取一个元素
choice
import random print(random.choice(['asd','ad',23,65])) >>>>>>>>>>>>>>>>>>>>> 23
随机抽样,且可自定义抽取个数
sample
import random print(random.sample(['花花','红红','江江',123,141],2)) #返回为一个列表格式 >>>>>>>>>>>>>>>>>>>>>>>>>>>> [141, '花花']
打乱排序
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, '小王', '大王']2.1、随机模块应用于验证码
思路及要求
- 大小写随机随机的五个字符
- 定义一个随机的0-9整数
- 定义一个随机的A-Z的大写字母
- 定义一个随机的a-z的小写字母
- 再最后从上三种可能中 随机取5次
def verification_code():
import random
a=''
#循环5次 可以同福哦传参 更改验证码个数
for i in range(5):
number=str(random.randint(0,9))
letter_up=chr(random.randint(65,90))
letter_lower=chr(random.randint(97,122))
data=random.choice([number,letter_up,letter_lower])
a+=data
return a
print(verification_code())
3、hashlib 加密模块
加密 是指将 人能看的懂得明文数据经过处理之后变成人看不懂得密码数据得过程
加密得作用
可以大大降低一些敏感数据得泄露
判断该数据是否已加密
一般情况下 如果一串没有规则得数字字母符号得组合一般都是经过加密之后得结果
加密算法
就是对铭文数据采用加密策略,不同得加密算法复杂度不一样,得出得结果长短也不一样
通常情况下,加密之后得结果越长,说明采用得加密算法越复杂
常见得加密算法
md5 sha系列 hmac base64
import hashlib md5=hashlib.md5() # 选择md5加密算法作为数据得加密策略 md5.update(b'123') #添加明文数据,数据必须要是bytes类型 res=md5.hexdigest() #获取加密之后得结果 print(res) #打印结果 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 202cb962ac59075b964b07152d234b703.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) >>>>>>>>>>>>>>>>> 4297f44b13955235245b2497399d7a93
加盐处理
为了防止 密文与对应的明文已经被人存储 所以我们可以通过加密时添加一些干扰项 来防止密码重复
password = input('password>>>:').strip()
md5.update('公司设置的盐(干扰项)'.encode('utf8'))
md5.update(password.encode('utf8'))
res = md5.hexdigest()
print(res) # 78bf5bd131c520b54168206d75f9f9be
动态加盐
动态加盐 就是将加盐处理的干扰项每次都不一样
例如 将干扰项设置为当时的时间 ,或者每个用户 用户名截取一段
3.1.2、加密应用场景场景一 用户密码加密
注册时直接存储密文
登录时密码比对也是比对的密文
场景二 文件安全性校验
正规的软件程序写完之后 做一个内容的加密,网址提供软件 文件记忆该文件内容对应的密文
用户下载完后不直接运行,而是对下载的内容做加密 然后比对两次密文是否一致 如果一致,表示文件没有被改,如果不一致 则表示该程序被更改过 可能被植入病毒
大文件加密优化
当程序文件过大时,直接全部加密太慢时,可以对一部分加密,例如每隔500M读取30bytes
4、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'))
5、日志模块
日志模块一般使用可以直接cv
日志的作用:为了记入事物发生的事实(史馆)
如何使用日志模块
- 日志等级
import logging
logging.debug('事件') #等级 10
logging.info('事件') #等级20
logging.warning('事件') # 等级30 #一般默认从warning级别开始记录日志
logging.error('事件') # 等级40
logging.critical('事件') #等级50
- 基本使用
import logging
file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8', )
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
handlers=[file_handler, ],
level=logging.ERROR)
logging.error('我不好!!!')
5.1、日志模块组成部分
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 登录成功')
5.2、实战应用
字典数据是日志模块固定的配置 写完一次之后几乎都不需要改动
所以它属于配置文件
配置文件中变量名推荐全大写
def get_logger(data):
# 记录日志
logging.config.dictConfig(settings.LOGGING_DIC) # 自动加载字典中的配置
logger1 = logging.getLogger(data)
# logger1.debug(f'{username}注册成功') # 这里让用户自己写更好
return logger1
#将日志模块使用封装为函数,并将最后一步警告等级和写入事件 通过返回值 返回的变量名 在外界进行编写
get_logger('注册记录').debug('新用户jason注册成功')
作业
多页爬取数据 因为 网站的人机校验 反爬机制 无法展示
只需将requests.get 发送的网址设置一个可变 格式化输出 将网址
for i in range(1,11):
res=requests.get(f'https://hz.fang.lianjia.com/loupan/fuyang/pg{i}/')
with open(r'fy.html','ab')as fy_w:
fy_w.write(res.content)
```
来循环导入数据至html 再正则筛选即可



