openpyxl模块读数据,random随机数模块,hashlib加密模块,subprocess模块
上一次我们通过openpyxl模块写入了一个三头牛的excel表格,这次我们继续通过openyxl模块读取表格中的内容。

下面通过.sheetname查看当前excel文件的表单名

提取excel表单中元素

按照列格式输出

按照行格式输出

首先你要先自行下载pandas第三方模块,同时你还要拥有
前戏:
通过pandas.DataFrame()操作排版字典里的文档,在通过.to_excel('目标文件')导入到excel表格中

注:
在这个过程中我们虽然没有见到
接下来我们运用
import requests
# res = requests.get('https://sh.lianjia.com/ershoufang/')
# # 仅仅只能获取一页数据 爬虫知识点也是很多的 没你想的那么简单
# with open(r'lj.html','wb') as f:
# f.write(res.content)
with open(r'lj.html', 'r', encoding='utf8') as f:
data = f.read()
# 1.研究目标数据 筛选
home_title_list = re.findall(
'<a class="" href=".*?" target="_blank" data-log_index=".*?" data-el="ershoufang" data-housecode=".*?" data-is_focus="" data-sl="">(.*?)</a>',
data
)
home_name_list = re.findall(
'<a href=".*?" target="_blank" data-log_index=".*?" data-el="region">(.*?) </a>',
data
)
home_addr_list = re.findall(
' - <a href=".*?" target="_blank">(.*?)</a>',
data
)
home_info_list = re.findall(
'<div class="houseInfo"><span class="houseIcon"></span>(.*?)</div>',
data
)
home_others_list = re.findall(
'<div class="followInfo"><span class="starIcon"></span>(.*?)</div>',
data
)
home_total_price = re.findall(
'<div class="totalPrice totalPrice2"><i> </i><span class="">(.*?)</span><i>万</i></div>',
data
)
home_unit_price = re.findall(
'<div class="unitPrice" data-hid=".*?" data-rid=".*?" data-price=".*?"><span>(.*?)</span></div>',
data
)
d = {
'房屋标题':home_title_list,
'小区名称':home_name_list,
'所在街道':home_addr_list,
'具体信息':home_info_list,
'其他信息':home_others_list,
'房屋总价':home_total_price,
'房屋单价':home_unit_price
}
df = pandas.DataFrame(d)
df.to_excel(r'333.xlsx')
random随机数模块
random随机数模块是一个内置模块,它的主要作用是产生随机数。
1 .random()
用法:random.random()
import random
print(random.random()) # 返回0到1之间随机的小数 0.5789942387957268
2 .randint()
用法:random.randint(参数一,参数二) 参数只能是正数和负数
import random
print(random.randint(1, 6)) # 4
3 .choice()
用法:random.choice(['参数一',‘参数二','参数n']) 随机抽取一个
import random
print(random.choice(['一等奖', '二等奖', '三等奖', '谢谢惠顾'])) # 一等奖
4 .sample()
用法:random.choice(['参数一',‘参数二','参数n'], 想要抽取的个数) 随机抽取,抽取的个数自己定
import random
print(random.sample(['慢男', '快男', '猛男', '老六', '老七', '男男', '老八秘制小汉堡'], 3)) # ['猛男', '老七', '快男']
5 . shuffle()
用法:random.shuffle('参数') 随机打乱顺序
import random
l1 = [2, 3, 4, 5, 6, 7, 8, 9, 10, 100]
random.shuffle(l1)
print(l1) # [7, 5, 100, 4, 10, 3, 9, 8, 2, 6]
6 搜狗python工程师笔试题
import random
code = '' # 定义全局变量用于存储所有的验证码
# 编写python代码 产生五位随机验证码(数字、小写字母、大写字母)
for i in range(5):
# 每次循环都应该产生 数字 小写字母 大写字母
random_int = str(random.randint(0, 9)) # 随机产生一个数字
random_lower = chr(random.randint(97, 122)) # 随机产生一个小写字母 chr(将数字作为ascii转换为英文字母)
random_upper = chr(random.randint(65, 90)) # 随机产生一个大写字母
# 从上述三个数据值中随机挑选一个作为验证码的一位数据
temp = random.choice([random_int, random_lower, random_upper])
code += temp # 拼接字符串
print(code) # 4x2qR
对于上述代码还能再次优化,通过封装成函数的方式,将验证码的位数不局限于四位。
def get_code(n):
code = '' # 定义全局变量用于存储所有的验证码
# 编写python代码 产生五位随机验证码(数字、小写字母、大写字母)
for i in range(n):
# 每次循环都应该产生 数字 小写字母 大写字母
random_int = str(random.randint(0, 9)) # 随机产生一个数字
random_lower = chr(random.randint(97, 122)) # 随机产生一个小写字母
random_upper = chr(random.randint(65, 90)) # 随机产生一个大写字母
# 从上述三个数据值中随机挑选一个作为验证码的一位数据
temp = random.choice([random_int, random_lower, random_upper])
code += temp # 拼接字符串
return code
res = get_code(4)
print(res) # Khdh
res1 = get_code(10)
print(res1) # PSnjX0CPYh
hashlib加密模块
1.什么叫hash:
| hash是一种加密算法(不同的hash算法只是复杂度不一样)(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法),该算法接受传入的内容,经过运算得到一串hash值(也就是密文) |
2..常见加密算法
md5 sha系列 hmac base64
| MD5是最常见的摘要算法,速度很快,生成结果是固定的16字节,通常用一个32位的16进制字符串表示。SHA1算法更安全点,它的结果是20字节长度,通常用一个40位的16进制字符串表示。而比SHA1更安全的算法是SHA256和SHA512等等,不过越安全的算法越慢,并且摘要长度更长 |
3.代码实参
import hashlib
md5 = hashlib.md5() # 选择md5加密算法作为数据的加密策略
md5.update(b'123') # 往里面添加明文数据 数据必须是bytes类型
res = md5.hexdigest() # 获取加密之后的结果
print(res) # 202cb962ac59075b964b07152d234b70
4.不能由hash值(密文)返解成内容
|
202cb962ac59075b964b07152d234b70
|
5.只要传入的明文的内容一样,得到的hash值(密文)必然一样
import hashlib
md5 = hashlib.md5() # 选择md5加密算法作为数据的加密策略
# md5.update(b'123') # 往里面添加明文数据 数据必须是bytes类型
# md5.update(b'hello') # 往里面添加明文数据 数据必须是bytes类型
# md5.update(b'jason') # 往里面添加明文数据 数据必须是bytes类型
# res = md5.hexdigest()
# print(res) # 31b9a81dc788368469ee4b78877eb1eb
md5.update(b'123hellojason')
res = md5.hexdigest()
print(res) # 31b9a81dc788368469ee4b78877eb1eb
6.加盐处理(salt)
|
什么叫加盐? 加盐通常指的是加盐加密,加盐加密是一种对系统登录口令的加密方式,它实现的方式是将每一个口令同一个叫做”盐“(salt)的n位随机数相关联。无论何时只要口令改变,随机数就改变。随机数以未加密的方式存放在口令文件中,这样每个人都可以读。不再只保存加密过的口令,而是先将口令和随机数连接起来然后一同加密,加密后的结果放在口令文件中。 |
password = input('password>>>:').strip()
md5.update('公司设置的盐(干扰项)'.encode('utf8'))#实例化md5的时候可以给传入参数,这叫加盐,此时盐值为'公司设置的盐(干扰项)'
md5.update(password.encode('utf8'))
res = md5.hexdigest()
print(res) # 78bf5bd131c520b54168206d75f9f9be
7.动态加盐(salt)
| 干扰项每次都不一样 eg:每次获取当前时间 每个用户用户名截取一段 |
8.加密实际应用场景
| 1.用户密码加密 注册存储密文 登录也是比对密文 2.文件安全性校验 正规的软件程序写完之后做一个内容的加密 网址提供软件文件记忆该文件内容对应的密文 用户下载完成后不直接运行 而是对下载的内容做加密 然后比对两次密文是否一致 如果一致表示文件没有被改 不一致则表示改程序有可能被植入病毒 3.大文件加密优化 程序文件100G 一般情况下读取100G内容然后全部加密 太慢 不对100G所有的内容加密 而是截取一部分加密 eg:每隔500M读取30bytes |
|
subprocess是python内置的模块,这个模块中的Popen可以查看用户输入的命令行是否存在 如果存在,把内容写入到stdout管道中。如果不存在,把信息写入到stderr管道 |
import subprocess
cmd = input('请输入您的指令>>>:').strip()
sub = subprocess.Popen(cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# stdout执行命令之后正确的返回结果
print(sub.stdout.read().decode('gbk'))
# stderr执行命令报错之后的返回结果
print(sub.stderr.read().decode('gbk'))
日志模块(logging)
日志模块就是记录我们在执行操作的历史记录
日志等级(默认从warning级别开始记录日志)
| 方法 | 等级 | 数字模式的等级 |
| .debug() | debug等级 | 10 |
| .info() | info等级 | 20 |
| .warning() | warning等级 | 30 |
| .error() | error等级 | 40 |
| .critical() | critical等级 | 50 |
日志等级的作用
| 日志等级(低到高) | 作用 |
| DEBUG | 程序调试bug时使用 |
| INFO | 程序正常运行时使用 |
| WARNING | 程序未按预期运行时使用,但并不是错误,如:用户登录密码错误 |
| ERROR | 程序出错误时使用,如:IO操作失败 |
| CRITICAL |
特别严重的问题,导致程序不能再继续运行时使用,如:磁盘空间为空,一般很少使 用 默认的是WARNING等级,当在WARNING或WARNING之上等级的才记录日志信息 |
| 日志等级从低到高的顺序是: DEBUG <info < warning error critical |
基本使用
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('我不好!!!')
| 日志的组成部分 | 对象 | 例子 | 作用 |
| 1.日志的产生(准备原材料) | logger对象 | logger = logging.getLogger('购物车记录') | 生成一个日志框架 |
| 2.日志的过滤(剔除不良品) | filter对象>>>:可以忽略 不用使用 |
|
|
| 3.日志的产出(成品) | handler对象 |
hd1 = logging.FileHandler('a1.log', encoding='utf-8') hd2 = logging.FileHandler('a2.log', encoding='utf-8') hd3 = logging.StreamHandler() |
输出成品 hd1输出到文件中 hd2输出到文件中 hd3输出到终端 |
|
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', ) |
控制日志的格式 fm1: 2022-07-21 20:12:21 PM fm2: 2022-07-21 |
根据上述表格添加下列步骤
5.给logger对象绑定handler对象
logger.addHandler(hd1) #输出到a1.log文件中
logger.addHandler(hd2) #输出到a2.log文件中
logger.addHandler(hd3) #输出到终端
6.给handler绑定formmate对象
hd1.setFormatter(fm1) # 以这样的格式记录:2022-07-21 20:12:21 PM
hd2.setFormatter(fm2) # 以这样的格式记录:2022-07-21
hd3.setFormatter(fm1) # 以这样的格式记录:2022-07-21 20:12:21 PM
7.设置日志等级作用 (见上面的日志等级作用表)
logger.setLevel(10) # debug
8.记录日志 (每执行一次记录一次)
logger.debug('写了半天 好累啊 好热啊')
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.warning('尊敬的VIP客户 晚上好 您又来啦')
# logger1 = logging.getLogger('注册记录')
# logger1.debug('jason注册成功')
logger1 = logging.getLogger('红浪漫顾客消费记录')
logger1.debug('慢男 猛男 骚男')


浙公网安备 33010602011771号