openpyxl模块读数据,random随机数模块,hashlib加密模块,subprocess模块

  • openpyxl模块读数据

  • 爬取链家二手房数据

  • random随机数模块

  • hashlib加密模块

  • subprocess模块


openpyxl模块读数据

上一次我们通过openpyxl模块写入了一个三头牛的excel表格,这次我们继续通过openyxl模块读取表格中的内容。

         

 

 

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

 

 

提取excel表单中元素 

 

 按照列格式输出

 

按照行格式输出


爬取链家二手房数据

  首先你要先自行下载pandas第三方模块,同时你还要拥有openpyxl模块,否则pandas模块无法使用

 

前戏:

  通过pandas.DataFrame()操作排版字典里的文档,在通过.to_excel('目标文件')导入到excel表格中

               

注:

  在这个过程中我们虽然没有见到openpyxl模块,其实是openpyxl是pandas的底层,在pandas运行的时候openpyxl也在运行

 

接下来我们运用openpyxl模块之前的知识进行爬取链家https://sh.lianjia.com/ershoufang/的网页信息:

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更安全的算法是SHA256SHA512等等,不过越安全的算法越慢,并且摘要长度更长

3.代码实参

 import hashlib
    md5 = hashlib.md5()  # 选择md5加密算法作为数据的加密策略
    md5.update(b'123')  # 往里面添加明文数据 数据必须是bytes类型
    res = md5.hexdigest()  # 获取加密之后的结果
    print(res)  # 202cb962ac59075b964b07152d234b70

4.不能由hash值(密文)返解成内容

202cb962ac59075b964b07152d234b70


    所谓的反解密很多时候其实是偷换概念 
        提前假设别人的密码是什么 然后用各种算法算出对应的密文
        之后构造对应关系 然后比对密文 最终映射明文
            {'密文1':123,'密文2':321,...}

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模块

  作用:模拟计算机cmd命令窗口

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('慢男 猛男 骚男')

 

posted @ 2022-07-21 21:04  没错,干就完了!  阅读(122)  评论(0)    收藏  举报