openpyxl模块读数据
from openpyxl import Workbook, load_workbook
wb = Workbook()
wb1 = wb.create_sheet('王老五消费记录')
wb2 = wb.create_sheet('老八消费记录')
wb3 = wb.create_sheet('老六消费记录')
wb1.append(['commodity', 'quantity', 'total'])
wb1.append(['威士忌', 2, 22000])
wb1.append(['雪茄', 10, 10000])
wb1.append(['法国大餐', 1, 10000000])
wb.save(r'111.xlsx')
# openpyxl模块读数据
wb = load_workbook(r'111.xlsx', data_only=True)
print(wb.sheetnames) # 查看excel文件中所有的工作簿名称 ['Sheet', '王老五消费记录', '老八消费记录', '老六消费记录']
wb1 = wb['王老五消费记录']
print(wb1.max_row) # 4 当前表格最大行数
print(wb1.max_column) # 3 当前表格最大列数
print(wb1['A1'].value) # commodity
print(wb1.cell(row=2, column=2).value) # 第二种取值方式 2
for i in wb1.rows:
print([j.value for j in i])
# ['commodity', 'quantity', 'total']
# ['威士忌', 2, 22000]
# ['雪茄', 10, 10000]
# ['法国大餐', 1, 10000000]
for j in wb1.columns:
print([i.value for i in j])
# ['commodity', '威士忌', '雪茄', '法国大餐']
# ['quantity', 2, 10, 1]
# ['total', 22000, 10000, 10000000]
pandas模块
封装了openpyxl的pandas模块操作excel表格的方式
import pandas
d = {
'食物种类': ['烧烤', '火锅', '炸鸡', '奶茶'],
'主要种类': ['烤茄子', '红油火锅', '蜜汁手扒鸡', '茉莉奶绿'],
'价格': [18, 150, 22, 13],
}
df = pandas.DataFrame(d)
df.to_excel(r'222.xlsx')
爬取链家二手房数据
import pandas as pandas
import requests
import re
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简介
random 模块实现了各种分布的伪随机数生成器
random 模块作用:主要用于生成随机数
random模块方法
方法 | 描述 |
---|---|
random.seed( ) | 初始化随机数生成器 |
random.randrange() | 从 range(start, stop, step) 返回一个随机选择的元素 |
random.random() | 返回0到1之间随机的小数 |
random.randint(a, b) | 返回随机整数 N 满足 a <= N <= b |
random.choice(seq) | 从非空序列 seq 返回一个随机元素。 如果 seq 为空,则引发 IndexError |
random.sample() | 随机抽样 自定义抽取个数 |
random.shuffle() | 随机打乱位置 |
代码演示
import random
# random.random()
print(random.random()) # 随机生成小数
# random.randint(a, b)
print(random.randint(0, 9)) # 返回0到9之间随机的整数,包括0和9
# random.choice(seq)
print(random.choice(['特等奖', '一等奖', '二等奖', '三等奖', '谢谢惠顾'])) # 随机抽取一个
# random.sample()
print(random.sample(['慢男', '快男', '猛男', '老六', '老七', '老八'], 3)) # # 随机抽样,自定义抽取个数
# random.shuffle()
l1 = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A', '大王', '小王']
random.shuffle(l1)
print(l1) # 随机打乱位置
案例实操
"""搜狗python工程师笔试题"""
# 编写python代码 产生五位随机验证码(数字、小写字母、大写字母)
import random
code = '' # 定义全局变量用于存储所有的验证码
for i in range(5):
# 每次循环都应该产生数字、小写字母、大写字母
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 # 拼接字符串
print(code)
# 编写python代码 产生随机验证码(数字、小写字母、大写字母)
import random
def get_code(n):
code = '' # 定义全局变量用于存储所有的验证码
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) # 产生五位随机验证码(包括数字、小写字母、大写字母)
res1 = get_code(10)
print(res1) # 产生十位随机验证码(包括数字、小写字母、大写字母)
hashlib加密模块
hashlib加密模块用于加密相关的操作,3.X里代替了md5模块和sha模块,主要提供SHA1,SHA224,SHA256,SHA384,SHA512,MD5算法 (sha比md5 更复杂、md5 不能反解)
简介
-
hashlib加密模块具体应用:用于网站防篡改
-
hashlib加密模块具体方法:监控网站被篡改,定时的去wget 去下载,然后md5比对 ,检查网站是否被篡改
-
加密:将明文数据(看得懂)经过处理之后变成密文数据(看不懂)的过程
-
加密目的:不想让敏感的数据轻易的泄露
-
怎么判断数据是否已经加密:一般情况下如果是一串没有规则的数字字母符合的组合一般都是加密之后的结果
-
加密算法:对明文数据采用的加密策略,不同的加密算法复杂度不一样,得出的结果长短也不一样,通常情况下加密之后的结果越长,说明采用的加密算法越复杂
主要方法
名称 | 描述 |
---|---|
hashlib.md5() | 利用md5算法加密 |
hashlib.sha1() | 利用sha1算法加密 |
hashlib.sha224() | 利用sha224算法加密 |
hashlib.sha256() | 利用sha256算法加密 |
hashlib.sha384() | 利用sha384算法加密 |
hashlib.sha512() | 利用sha512算法加密 |
特有方法
名称 | 描述 |
---|---|
update(arg) | 可以重复利用指定了特殊加密算法的Hash对象,对arg 进行加密 |
digest() | 以字符形式返回加密内容 |
hexdigest() | 以16进制形式返回加密内容 |
copy() | 为了达到重复利用Hash对象的目的,而克隆Hash对象 |
代码实参
import hashlib
md5 = hashlib.md5() # 选择md5加密算法作为数据的加密策略
md5.update(b'123') # 往里面添加明文数据 数据必须是bytes类型
res = md5.hexdigest() # 获取加密之后的结果
print(res) # 202cb962ac59075b964b07152d234b70
只要明文数据是一样的那么采用相同的算法得出的密文肯定一样
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
加盐处理
对数字内容进行 Hash 运算,获取唯一的摘要值来指代原始完整的数字内容,利用 Hash 函数的抗碰撞性来确保内容未被篡改
常用于用户名和密码来确保用户信息安全,为了防止攻击会采用加盐的方法,就是原来的明文加上一个随机数之后的 Hash 值,Hash 值和盐会保存在两个地方,只要不是同时泄漏就很难被破解
动态加盐:干扰项每次都不一样(每次获取当前时间,每个用户用户名截取一段)
import hashlib
md5 = hashlib.md5()
password = input('password>>>:').strip()
md5.update('公司设置的盐(干扰项)'.encode('utf8'))
md5.update(password.encode('utf8'))
res = md5.hexdigest()
print(res) # 5598e2669b21bbe42fa952c1f4ab84e2
加密实际应用场景
-
用户密码加密:注册存储密文,登录也是比对密文
-
文件安全性校验:正规的软件程序写完之后做一个内容的加密,网址提供软件文件记忆该文件内容对应的密文,用户下载完成后不直接运行 而是对下载的内容做加密,然后比对两次密文是否一致 如果一致表示文件没有被改,不一致则表示改程序有可能被植入病毒
-
大文件加密优化:程序文件100G ,一般情况下读取100G内容然后全部加密太慢,而是截取一部分加密(每隔500M读取30bytes)
注意:加密之后的结果一般情况不能反解密,所谓的反解密很多时候其实是偷换概念,提前假设别人的密码是什么,然后用各种算法算出对应的密文,之后构造对应关系,然后比对密文,最终映射明文
subprocess远程命令模块
模拟计算机cmd命令窗口
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日志模块
日志概念
日志是一种可以追踪某些软件运行时所发生事件的方法。软件开发人员可以向他们的代码中调用日志记录相关的方法来表明发生了某些事情。一个事件可以用一个可包含可选变量数据的消息来描述。此外,事件也有重要性的概念,这个重要性也可以被称为严重性级别(level)。
作用
- 程序调试
- 了解软件程序运行情况,是否正常
- 软件程序运行故障分析与问题定位
logging模块简介
logging模块定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统。logging模块是Python的一个标准库模块,由标准库模块提供日志记录API的关键好处是所有Python模块都可以使用这个日志记录功能。所以,你的应用日志可以将你自己的日志信息与来自第三方模块的信息整合起来。
日志等级 | 描述 |
---|---|
DEBUG | 最详细的日志信息,典型应用场景是 问题诊断 |
INFO | 信息详细程度仅次于DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作 |
WARNING | 当某些不期望的事情发生时记录的信息(如,磁盘可用空间较低),但是此时应用程序还是正常运行的 |
ERROR | 由于一个更严重的问题导致某些功能不能正常运行时记录的信息 |
CRITICAL | 当发生严重错误,导致应用程序不能继续运行时记录的信息 |
开发应用程序或部署开发环境时,可以使用DEBUG或INFO级别的日志获取尽可能详细的日志信息来进行开发或部署调试;应用上线或部署生产环境时,应该使用WARNING或ERROR或CRITICAL级别的日志来降低机器的I/O压力和提高获取错误日志信息的效率。日志级别的指定通常都是在应用程序的配置文件中进行指定的。
import logging
logging.debug('debug等级') # 10
logging.info('info等级') # 20
logging.warning('warning等级') # 默认从warning级别开始记录日志 30
logging.error('error等级') # 40
logging.critical('critical等级') # 50
日志模板
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 = 'log.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('慢男 猛男 骚男')