正则表达式前戏
| 案例:京东注册手机号校验 |
| |
| 基本需求:手机号必须是11位、手机号必须以13 15 17 18 19开头、必须是纯数字 |
| |
| '''纯python代码实现''' |
| while True: |
| |
| phone_num = input('请输入您的手机号>>>:').strip() |
| |
| if len(phone_num) == 11: |
| |
| if phone_num.isdigit(): |
| |
| if phone_num.startswith('13') or phone_num.startswith('15') or phone_num.startswith( |
| '17') or phone_num.startswith('18') or phone_num.startswith('19'): |
| print('手机号码输入正确') |
| else: |
| print('手机号开头不对') |
| else: |
| print('手机号必须是纯数字') |
| else: |
| print('手机号必须是11位') |
| '''python结合正则实现''' |
| import re |
| |
| phone_number = input('please input your phone number: ') |
| if re.match('^(13|14|15|18)[0-9]{9}$', phone_number): |
| print('是合法的手机号码') |
| else: |
| print('不是合法的手机号码') |
| |
| """ |
| 正则表达式是一门独立的技术 所有编程语言都可以使用 |
| 它的作用可以简单的概括为:利用一些特殊符号(也可以直接写需要查找的具体字符)的组合产生一些特殊的含义然后去字符串中筛选出符合条件的数据 |
| >>>:筛选数据(匹配数据) |
| """ |
字符组
| '''字符组默认匹配方式是挨个挨个匹配''' |
| [0123456789] 匹配0到9任意一个数(全写) |
| [0-9] 匹配0到9任意一个数(缩写) |
| [a-z] 匹配26个小写英文字母 |
| [A-Z] 匹配26个大写英文字母 |
| [0-9a-zA-Z] 匹配数字或者小写字母或者大写字母 |
| ps:字符组内所有的数据默认都是或的关系 |
特殊符号
| '''特殊符号默认匹配方式是挨个挨个匹配''' |
| . 匹配除换行符以外的任意字符 |
| \w 匹配数字、字母、下划线 |
| \W 匹配非数字、非字母、非下划线 |
| \d 匹配数字 |
| ^ 匹配字符串的开头 |
| $ 匹配字符串的结尾 |
| 两者组合使用可以非常精确的限制匹配的内容 |
| a|b 匹配a或者b(管道符的意思是或) |
| () 给正则表达式分组 不影响表达式的匹配功能 |
| [] 字符组 内部填写的内容默认都是或的关系 |
| [^] 取反操作 匹配除了字符组里面的其他所有字符 |
| 注意上尖号在中括号内和中括号意思完全不同 |
量词
| '''正则表达式默认情况下都是贪婪匹配>>>:尽可能多的匹''' |
| * 匹配零次或多次 默认是多次(无穷次) |
| + 匹配一次或多次 默认是多次(无穷次) |
| ? 匹配零次或一次 作为量词意义不大主要用于非贪婪匹配 |
| {n} 重复n次 |
| {n,} 重复n次或更多次 默认是多次(无穷次) |
| {n,m} 重复n到m次 默认是m次 |
| ps:量词必须结合表达式一起使用 不能单独出现 并且只影响左边第一个表达式 |
| jason\d{3} 只影响\d |
课堂练习
| https://www.cnblogs.com/Dominic-Ji/articles/16046931.html |
| |
| 看jasonji的博客 |
贪婪匹配与非贪婪匹配
| """所有的量词都是贪婪匹配如果想要变为非贪婪匹配只需要在量词后面加问号""" |
| 待匹配的文本 |
| <script>alert(123)</script> |
| 待使用的正则(贪婪匹配) |
| <.*> |
| 请问匹配的内容 |
| <script>alert(123)</script> 一条 |
| |
| 待使用的正则(非贪婪匹配) |
| <.*?> |
转义符
| """斜杠与字母的组合有时候有特殊含义""" |
| \n 匹配的是换行符 |
| \\n 匹配的是文本\n |
| \\\\n 匹配的是文本\\n |
| ps:如果是在python中使用 还可以在字符串前面加r取消转义 |
正则表达式实战建议
| 1.编写校验用户身份证号的正则 |
| ^[1-9]\d{13,16}[0-9x]$ |
| ^[1-9]\d{14}(\d{2}[0-9x])?$ |
| ^([1-9]\d{16}[0-9x]|[1-9]\d{14})$ |
| 2.编写校验邮箱的正则 |
| 3.编写校验用户手机号的正则(座机、移动) |
| 4.编写校验用户qq号的正则 |
| |
| '''很多时候 很多问题 前人已经弄好了 你只需要花点时间找一找就可以''' |
| |
| ps:能够写出简单的正则 能够大致看懂复杂的正则 |
re模块
| 在python中如果想要使用正则 可以考虑re模块 |
| |
| import re |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ret = re.split('[ab]', 'abcd') |
| print(ret) |
| |
| ret = re.sub('\d', 'H', 'eva3jason4yuan4', 1) |
| print(ret) |
| |
| ret = re.subn('\d', 'H', 'eva3jason4yuan4') |
| print(ret) |
| |
re模块补充说明
| 1.分组优先 |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 2.分组别名 |
| res = re.search('www.(?P<content>baidu|oldboy)(?P<hei>.com)', 'www.oldboy.com') |
| print(res.group()) |
| print(res.group('content')) |
| print(res.group(0)) |
| print(res.group(1)) |
| print(res.group(2)) |
| print(res.group('hei')) |
作业讲解
| """ |
| 网络爬虫没有我们现在接触的那么简单 |
| 有时候页面数据无法直接拷贝获取 |
| 有时候页面还存在防爬机制 弄得不好ip会被短暂拉黑 |
| """ |
| 1.直接拷贝页面数据到本地文件 |
| 2.读取文件内容当做字符串处理 |
| 3.编写正则筛选内容 |
| import re |
| |
| |
| with open(r'redbull.html', 'r', encoding='utf8') as f: |
| |
| data = f.read() |
| |
| """ |
| 思路1: |
| 一次性获取每个公司全部的数据 |
| 分部分挨个获取最后统一整合 |
| """ |
| |
| |
| |
| comp_title_list = re.findall('<h2>(.*?)</h2>', data) |
| |
| comp_address_list = re.findall("<p class='mapIco'>(.*?)</p>", data) |
| |
| comp_email_list = re.findall("<p class='mailIco'>(.*?)</p>", data) |
| |
| comp_phone_list = re.findall("<p class='telIco'>(.*?)</p>", data) |
| |
| res = zip(comp_title_list, comp_address_list, comp_email_list, comp_phone_list) |
| |
| with open(r'comp_info.txt', 'w', encoding='utf8') as f: |
| for data_tuple in res: |
| print( |
| """ |
| 公司名称:%s |
| 公司地址:%s |
| 公司邮编:%s |
| 公司电话:%s |
| """ % data_tuple) |
| f.write( """ |
| 公司名称:%s |
| 公司地址:%s |
| 公司邮编:%s |
| 公司电话:%s\n |
| """ % data_tuple) |
第三方模块的下载与使用
| 第三方模块:别人写的模块 一般情况下功能都特别强大 |
| |
| 我们如果想使用第三方模块 第一次必须先下载后面才可以反复使用(等同于内置模块) |
| |
| 下载第三方模块的方式 |
| 1.pip工具 |
| 注意每个解释器都有pip工具 如果我们的电脑上有多个版本的解释器那么我们在使用pip的时候一定要注意到底用的是哪一个 否则极其任意出现使用的是A版本解释器然后用B版本的pip下载模块 |
| 为了避免pip冲突 我们在使用的时候可以添加对应的版本号 |
| python27 pip2.7 |
| python36 pip3.6 |
| python38 pip3.8 |
| 下载第三方模块的句式 |
| pip install 模块名 |
| 下载第三方模块临时切换仓库 |
| pip install 模块名 -i 仓库地址 |
| 下载第三方模块指定版本(不指定默认是最新版) |
| pip install 模块名==版本号 -i 仓库地址 |
| 2.pycharm提供快捷方式 |
| 群内截图 |
| |
| """ |
| 下载第三方模块可能会出现的问题 |
| 1.报错并有警告信息 |
| WARNING: You are using pip version 20.2.1; |
| 原因在于pip版本过低 只需要拷贝后面的命令执行更新操作即可 |
| d:\python38\python.exe -m pip install --upgrade pip |
| 更新完成后再次执行下载第三方模块的命令即可 |
| 2.报错并含有Timeout关键字 |
| 说明当前计算机网络不稳定 只需要换网或者重新执行几次即可 |
| 3.报错并没有关键字 |
| 面向百度搜索 |
| pip下载XXX报错:拷贝错误信息 |
| 通常都是需要用户提前准备好一些环境才可以顺利下载 |
| 4.下载速度很慢 |
| pip默认下载的仓库地址是国外的 python.org |
| 我们可以切换下载的地址 |
| pip install 模块名 -i 仓库地址 |
| pip的仓库地址有很多 百度查询即可 |
| 清华大学 :https://pypi.tuna.tsinghua.edu.cn/simple/ |
| 阿里云:http://mirrors.aliyun.com/pypi/simple/ |
| 中国科学技术大学 :http://pypi.mirrors.ustc.edu.cn/simple/ |
| 华中科技大学:http://pypi.hustunique.com/ |
| 豆瓣源:http://pypi.douban.com/simple/ |
| 腾讯源:http://mirrors.cloud.tencent.com/pypi/simple |
| 华为镜像源:https://repo.huaweicloud.com/repository/pypi/simple/ |
| """ |
网络爬虫模块之requests模块
| requests模块能够模拟浏览器发送网络请求 |
| |
| import requests |
| |
| |
| |
| |
| |
| |
| |
网络爬虫实战之爬取链家二手房数据
| import requests |
| import re |
| |
| res = requests.get('https://sh.lianjia.com/ershoufang/pudong/') |
| |
| data = res.text |
| |
| 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_street_list = re.findall( |
| '<div class="positionInfo"><span class="positionIcon"></span><a href=".*?" target="_blank" data-log_index=".*?" data-el="region">.*? </a> - <a href=".*?" target="_blank">(.*?)</a> </div>', |
| data) |
| |
| home_info_list = re.findall('<div class="houseInfo"><span class="houseIcon"></span>(.*?)</div>', data) |
| |
| home_watch_list = re.findall('<div class="followInfo"><span class="starIcon"></span>(.*?)</div>', data) |
| |
| home_total_price_list = re.findall( |
| '<div class="totalPrice totalPrice2"><i> </i><span class="">(.*?)</span><i>万</i></div>', data) |
| |
| home_unit_price_list = re.findall( |
| '<div class="unitPrice" data-hid=".*?" data-rid=".*?" data-price=".*?"><span>(.*?)</span></div>', data) |
| |
| home_data = zip(home_title_list, home_name_list, home_street_list, home_info_list, home_watch_list, |
| home_total_price_list, home_unit_price_list) |
| with open(r'home_data.txt','w',encoding='utf8') as f: |
| for data in home_data: |
| print( |
| """ |
| 房屋标题:%s |
| 小区名称:%s |
| 街道名称:%s |
| 详细信息:%s |
| 关注程度:%s |
| 房屋总价:%s |
| 房屋单价:%s |
| """%data |
| ) |
| f.write(""" |
| 房屋标题:%s |
| 小区名称:%s |
| 街道名称:%s |
| 详细信息:%s |
| 关注程度:%s |
| 房屋总价:%s |
| 房屋单价:%s\n |
| """%data) |
自动化办公领域之openpyxl模块
| 1.excel文件的后缀名问题 |
| 03版本之前 |
| .xls |
| 03版本之后 |
| .xlsx |
| |
| 2.操作excel表格的第三方模块 |
| xlwt往表格中写入数据、wlrd从表格中读取数据 |
| 兼容所有版本的excel文件 |
| openpyxl最近几年比较火热的操作excel表格的模块 |
| 03版本之前的兼容性较差 |
| ps:还有很多操作excel表格的模块 甚至涵盖了上述的模块>>>:pandas |
| |
| 3.openpyxl操作 |
| '''学会看官方文档!!!''' |
| from openpyxl import Workbook |
| |
| wb = Workbook() |
| |
| wb1 = wb.create_sheet('学生名单') |
| wb2 = wb.create_sheet('舔狗名单') |
| wb3 = wb.create_sheet('海王名单') |
| |
| wb4 = wb.create_sheet('富婆名单', 0) |
| |
| wb4.title = '高富帅名单' |
| wb4.sheet_properties.tabColor = "1072BA" |
| |
| |
| |
| |
| |
| |
| wb4.append(['编号', '姓名', '年龄', '爱好']) |
| wb4.append([1, 'jason', 18, 'read']) |
| wb4.append([2, 'kevin', 28, 'music']) |
| wb4.append([3, 'tony', 58, 'play']) |
| wb4.append([4, 'oscar', 38, 'ball']) |
| wb4.append([5, 'jerry', 'ball']) |
| wb4.append([6, 'tom', 88,'ball','哈哈哈']) |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| wb.save(r'111.xlsx') |
| |
| """ |
| openpyxl主要用于数据的写入 至于后续的表单操作它并不是很擅长 如果想做需要更高级的模块pandas |
| |
| import pandas |
| |
| data_dict = { |
| "公司名称": comp_title_list, |
| "公司地址": comp_address_list, |
| "公司邮编": comp_email_list, |
| "公司电话": comp_phone_list |
| } |
| # 将字典转换成pandas里面的DataFrame数据结构 |
| df = pandas.DataFrame(data_dict) |
| # 直接保存成excel文件 |
| df.to_excel(r'pd_comp_info.xlsx') |
| |
| |
| excel软件正常可以打开操作的数据集在10万左右 一旦数据集过大 软件操作几乎无效 |
| 需要使用代码操作>>>:pandas模块 |
| """ |
hashlib加密模块
| 1.何为加密 |
| 将明文数据处理成密文数据 让人无法看懂 |
| 2.为什么加密 |
| 保证数据的安全 |
| 3.如何判断数据是否是加密的 |
| 一串没有规律的字符串(数字、字母、符号) |
| 4.密文的长短有何讲究 |
| 密文越长表示使用的加密算法(数据的处理过程)越复杂 |
| 5.常见的加密算法有哪些 |
| md5 base64 hmac sha系列 |
| 6.加密算法基本操作 |
| import hashlib |
| |
| md5 = hashlib.md5() |
| |
| md5.update(b'hello') |
| |
| res = md5.hexdigest() |
| print(res) |
加密补充说明
| 1.加密算法不同 内容如果相同 那么结果肯定相同 |
| md5.update(b'hello~world~python~666') |
| |
| md5.update(b'hello') |
| md5.update(b'~world') |
| md5.update(b'~python~666') |
| 2. 加密之后的结果是无法反解密的 |
| 只能从明文到密文正向推导 无法从密文到明文反向推导 |
| 常见的解密过程其实是提前猜测了很多结果 |
| 123 密文 |
| 321 密文 |
| 222 密文 |
| 3.加盐处理 |
| 在明文里面添加一些额外的干扰项 |
| |
| md5 = hashlib.md5() |
| |
| md5.update('公司设置的干扰项'.encode('utf8')) |
| md5.update(b'hello python') |
| |
| res = md5.hexdigest() |
| print(res) |
| |
| 4.动态加盐 |
| 干扰项是随机变化的 |
| eg:当前时间、用户名部分... |
| 5.加密实战操作 |
| 1.用户密码加密 |
| 2.文件安全性校验 |
| 3.文件内容一致性校验 |
| 4.大文件内容加密 |
| 截取部分内容加密即可 |
subporcess模块
| 模拟操作系统终端 执行命令并获取结果 |
| |
| import subprocess |
| |
| res = subprocess.Popen( |
| 'asdas', |
| shell=True, |
| stdin=subprocess.PIPE, |
| stdout=subprocess.PIPE, |
| ) |
| print('正确结果', res.stdout.read().decode('gbk')) |
| print('错误结果', res.stderr) |
logging日志模块
| 1.如何理解日志 |
| 简单的理解是记录行为举止的操作 |
| 2.日志的级别 |
| 五种级别 |
| 3.日志模块要求 |
| 代码无需掌握 但是要会cv修改 |
| |
| import logging |
| |
| |
| |
| |
| |
| file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf8',) |
| 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.产生日志 |
| 2.过滤日志 |
| 基本不用 因为在日志产生的阶段就可以控制自己想要的日志内容 |
| 3.输出日志 |
| 4.日志格式 |
| |
| import logging |
| |
| |
| logger = logging.getLogger('购物车记录') |
| |
| |
| hd1 = logging.FileHandler('a1.log', encoding='utf-8') |
| hd2 = logging.FileHandler('a2.log', encoding='utf-8') |
| hd3 = logging.StreamHandler() |
| |
| 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', |
| ) |
| |
| logger.addHandler(hd1) |
| logger.addHandler(hd2) |
| logger.addHandler(hd3) |
| |
| hd1.setFormatter(fm1) |
| hd2.setFormatter(fm2) |
| hd3.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]' |
| simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' |
| |
| logfile_path = 'a3.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' |
| }, |
| |
| 'default': { |
| 'level': 'DEBUG', |
| 'class': 'logging.handlers.RotatingFileHandler', |
| 'formatter': 'standard', |
| 'filename': logfile_path, |
| 'maxBytes': 1024 * 1024 * 5, |
| 'backupCount': 5, |
| 'encoding': 'utf-8', |
| }, |
| }, |
| 'loggers': { |
| |
| '': { |
| 'handlers': ['default', 'console'], |
| 'level': 'DEBUG', |
| 'propagate': True, |
| }, |
| |
| |
| |
| |
| |
| }, |
| } |
| logging.config.dictConfig(LOGGING_DIC) |
| |
| |
| |
| |
| logger1 = logging.getLogger('红浪漫顾客消费记录') |
| logger1.debug('慢男 猛男 骚男') |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)