内置函数的补充
补充内置模块
目录
- 爬取链家二手房数据
- random 随机数模块
- hashlib 加密模块
- subprocess 模块
- 日志模块
爬取链接二手房数据
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'123.xlsx')
random模块
-
random 模块的方法
方法 作用 random( ) 随机一个大于0 小于1 的小数 uniform(a,b ) 随机一个大于a 小于b 的小数 randint(a,b) 随机一个大于a小于b的整数 choice() 随机抽取一个 sample( ,n) 随机抽样 自定义抽取个数 shuffle( ) 随机打乱列表中的顺序 -
random 方法的实例
随机参数五位代码: import random def get_code(n): # 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)
hashlib 加密模块
-
什么是加密
加密就是将看的懂的数据封装成类似于摩斯密码的密文数据的过程
-
如何判断加密
若为一串看不懂的数字字母组合则就是加密后的结果
-
加密的算法
就是对明文数据采用的加密策略
不同的加密算法复杂度不一样 得出的结果长短也不一样
通常情况下加密之后的结果越长 说明采用的加密算法越复杂 -
常见的加密算法
md5 sha系列 hmac base64
-
代码实现
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) md5.update(b'123hellojason') res = md5.hexdigest() print(res)
-
加盐处理(salt)
password = input('password>>>:').strip() md5.update('公司设置的盐(干扰项)'.encode('utf8')) md5.update(password.encode('utf8')) res = md5.hexdigest() print(res)
-
动态加盐
干扰项每次都不一样
每次获取当前时间 每个用户用户名截取一段 -
加密适用的场景
-
用户密码加密
注册存储密文 登录也是比对密文
-
文件安全性校验
在操作完毕后,正规软件会对其进行一个加密处理,网址提供软件文件记忆该文件内容对应的密文
用户下载完成后不直接运行 而是先对下载的内容做加密,然后比对密文是否一致
-
大文件加密
对大文件加密就是对大文件进行截取加密
-
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'))
日志模块
-
日志的作用
为了记录事物发生的事实
-
日志的等级
等级名称 等级 debug 10 info 20 warning 30 error 40 critical 50 默认从warning 级别开始记录日志
-
日志的格式
-
日志的组成部分
组成部分 意义 展示 日志的产生(准备原材料) logger对象 logger = logging.getLogger 日志的过滤(剔除不良品) filter对象>>>:可以忽略 不用使用 None
日志的产出(成品)
handler对象hd1 = logging.FileHandler('a1.log', encoding='utf-8') # 输出到文件中
hd2 = logging.StreamHandler() # 输出到终端
日志的格式(包装)
format对象fm1 = logging.Formatter(
fmt='%(asctime)s - %(name)s: %(message)s',
datefmt='%Y-%m-%d',)给logger对象绑定handler对象 None logger.addHandler(hd1) 给handler绑定formmate对象 None hd1.setFormatter(fm1) 设置日志等级 ()中为级别 logger.setLevel(10) 记录日志 输入表达日志的内容 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('慢男 猛男 骚男')