day20
昨日内容回顾
-
正则表达式前戏
# 正则表达式 利用一些特殊符号的组合去字符串中筛选出符合条件的数据 # 特点 属于一门独立的学科 其实内容非常的多 而我们之需要了解个大概即可 ps:推荐读物>>>:正则指引
-
字符组
# 中括号括起来 内部存放多个元素 元素之间是或的关系 [a-z0-9A-Z] '''正则表达式在没有量词修饰的情况下默认都是一个个匹配'''
-
特殊符号
. 除换行符以外的任意字符 \w 数字、字母、下划线 \d 数字 ^ 以...开头 $ 以...结尾 () 对正则表达式进行分组 不影响匹配 | 或 [^] 对中括号内的数据取反 '''正则表达式在没有量词修饰的情况下默认都是一个个匹配'''
-
量词
# 量词不能单独使用 必须跟着正则表达式的后面 默认只影响紧挨着的正则 ab+ 只影响b """所有的量词默认情况下都是贪婪匹配!!!(尽可能往多的匹)""" * 重复零次或者多次 + 重复一次或者多次 ? 重复零次或者一次 {n} 重复n次 {n,m} 重复n次到m次 {n,} 重复n次或者多次
-
课堂练习
复杂的正则表达式我们可以不会写 但是要能看懂个大概,然后结合百度搜索即可 # 站在巨人的肩膀上!!!
-
取消转义
斜杠与字母的组合在很多地方都有特殊含义 在正则表达式中取消转义可以使用斜杠 \\n 意思是匹配\n \\\\n 意思是匹配\\n 在python中还可以直接在字符串的前面加r r'\\n'
-
贪婪匹配与非贪婪匹配
# 1.默认都是贪婪匹配 .* # 2.在量词的后面加问号就会变成非贪婪匹配 .*? '''在使用.*或者.*?的时候 基本都需要左右两边指定条件'''
-
内置模块之re
re.findall() 全局查找所有符合条件的数据 re.search() 找到一个就结束 re.match() 必须从头匹配 re.compile() 提前定义好正则 后续不需要反复编写 re.finditer() 将结果制作成迭代器 节省空间
今日内容概要
给鸡哥找的
作业讲解。。。。
import re
# 摸你网络请求读取文件数据
with open(r'a.txt', 'r', encoding='utf8') as f:
# 2.由于数据量不大 这里直接一次性读取
file_data = f.read() # file_data就是待筛选的数据
# 3.研究所需数据的特征 再编写相应的正则
# 3.1.匹配公司名称 首先拿到公司名称所在的数据区域
# <h2>红牛杭州分公司</h2>
cp_title_list = re.findall('<h2>(.*?)</h2>', file_data)
print(cp_title_list)
# '''findall优先展示括号内正则表达式匹配到的内容''
# 3.2.匹配公司地址 首先拿到公司地址所在的数据区域
# <p class='mapIco'>杭州市上城区庆春路29号远洋大厦11楼A座</p>
cp_title_list1 = re.findall("<p class='mapIco'>(.*?)</p>", file_data)
print(cp_title_list1)
# 3.3.匹配公司邮编 首先拿到公司邮编所在的数据区域
# <p class='mailIco'>310009</p>
cp_title_list2 = re.findall("<p class='mailIco'>(.*?)</p>", file_data)
print(cp_title_list2)
# 3.4.匹配公司电话 首先拿到公司电话所在的数据区域
# <p class='telIco'>0571-87045279/7792</p>
cp_title_list3 = re.findall("<p class='telIco'>(.*?)</p>", file_data)
print(cp_title_list3)
# print(cp_phone_list)
# 4.有了四个列表 分别存储的时候公司名称 地址 电话 邮编 如何对应展示
# 4.1.使用zip先将每个公司所有的数据整合到一起
描述 zip
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
res = zip(cp_title_list,cp_title_list1,cp_title_list2,cp_title_list3)
for t in res:
print("""
公司名称:%s
公司地址:%s
公司邮编:%s
公司电话:%s
"""%t)
# 使用正则筛选出网站的数据(明天会讲 所以不用课后问)
# http://www.redbull.com.cn/about/branch
# 将公司名称 地址 邮编 电话筛选出来
# 展示可以是格式化输出也可以是文件存储
import re
import requests
res = requests.get(url='http://www.redbull.com.cn/about/branch') # 获取html源码
# print(res.text)
with(open('1.txt','wb')) as f1: # 存入1.txt文件中
for i in res:
f1.write(i)
# with(open('1.txt','w',encoding='utf8')) as f1:
# f1.write(res.text)
#data-describe='杭州市上城区庆春路29号远洋大厦11楼A座'>
# <h2>红牛杭州分公司</h2>
# <p class='mapIco'>杭州市上城区庆春路29号远洋大厦11楼A座</p>
# <p class='mailIco'>310009</p>
# <p class='telIco'>0571-87045279/7792</p>
res1 = re.compile('data-describe=\'(.*?)\'><h2>(.*?)</h2><p class=\'mapIco\'>(.*?)</p><p class=\'mailIco\'>(.*?)</p><p class=\'telIco\'>(.*?)</p>') # 自定义正则表达式
with(open('1.txt','r',encoding='utf8')) as f2:
res_txt = f2.read()
res2 = res1.findall(res_txt)
print(res2)
print(len(res2))
for i in res2:
print(f"""
公司名称:{i[1]}
地址:{i[2]}
邮编:{i[3]}
电话:{i[4]}
""")
re模块补充说明
re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
import re
# ret = re.findall('a(b)c', 'abcabcabcabc')
# print(ret) 打印结果 ['b', 'b', 'b', 'b']可以理解为优先显示
ret=re.findall('a(?:b)c','abcabcabcabc')
# print(ret) 打印结果 ['abc', 'abc', 'abc', 'abc']
# ret = re.findall('(a)(b)(c)', 'abcabcabcabc')
# print(ret) 打印结果# [('a', 'b', 'c'), ('a', 'b', 'c'), ('a', 'b', 'c'), ('a', 'b', 'c')]
ret = re.findall('(?P<aaa>a)(b)(c)', 'abcabcabcabc')
print(ret) # [('a', 'b', 'c'), ('a', 'b', 'c'), ('a', 'b', 'c'), ('a', 'b', 'c')]
print(ret.group('aaa')) cuo!!
findall 默认是 分组优先展示 正则表达式中如果有括号分组那么在显示的结果的·时候也会默认值显示括号里变得 取消分组展示就是 (?:) 括号前面加问号冒号
"""
# ret = re.search('a(b)c', 'abcabcabcabc')
# print(ret.group()) # abc
# print(ret.group(0)) # abc
# print(ret.group(1)) # b 可以通过索引的方式单独获取分组内匹配到的数据
# ret = re.search('a(b)(c)', 'abcabcabcabc')
# print(ret.group()) # abc
# print(ret.group(0)) # abc
# print(ret.group(1)) # b 可以通过索引的方式单独获取分组内匹配到的数据
# print(ret.group(2)) # c 可以通过索引的方式单独获取分组内匹配到的数据
'''针对search和match有几个分组 group方法括号内最大就可以写几'''
# 分组之后还可以给组起别名
# ret = re.search('a(?P<name1>b)(?P<name2>c)', 'abcabcabcabc')
# print(ret.group('name1')) # b
# print(ret.group('name2')) # c
collections模块
具名元组
具名元组(namedtuple) 是 python 标准库 collections 中的工厂函数。它接受两个参数,第一个参数表示类的名称,第二个参数是类的字段名。后者可以是可迭代对象,也可以是空格隔开的字符串。然后,我们通过一串参数的形式将参数传递到构造函数中。这样,我们既可以通过字段名访问元素,也可以用索引访问元素。
from collections import namedtuple
先产生一个元组对象模板
point=namedtuple('坐标',['x','y'])
创建诸多元素数据
p1=point(1,2)
p2=point(10,8)
print(p1,p2) # 坐标(x=1, y=2) 坐标(x=10, y=8)
print(p1.x) # 1
print(p1.y) # 2
双端队列
队列先进先出
默认是一端进一端出
双端队列 两端都可以进出
import queue
q = queue.Queue(3) # 最大只能放三个元素
# 存放元素
# q.put(123)
# q.put(321)
# q.put(222)
# q.put(444) # 如果队列满了 继续添加则原地等待
# 获取元素
# print(q.get()) # 123
# print(q.get()) # 321
# print(q.get()) # 222
# print(q.get()) # 如果队列空了 继续获取则原地等待
from collections import deque
q = deque([1,2,3])
print(q)
q.append(444) # 尾部添加元素
print(q)
q.appendleft(666) # 左边添加元素
print(q)
q.pop() # 默认尾部弹出元素
q.popleft() # 左边弹出元素
字典相关
正常的字典内部是无序 这个我们都知道
你看到的顺序只是 pycharm做的优化我们看一下有序字典
# # 有序字典
from collections import OrderedDict
d2 = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
print(d2)
d2['x'] = 111
d2['y'] = 222
d2['z'] = 333
print(d2)
print(d2.keys())
计数器、、
比方说统计某个字符串出现的字数或者全部字符出现的次数 跟len不一样 也有几分相似
res = 'abcdeabcdabcaba'
# new_dict = {}
# for i in res:
# if i not in new_dict:
# # 字符第一次出现 应该创建一个新的键值对
# new_dict[i] = 1
# else:
# new_dict[i] += 1
# print(new_dict) {'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1}
from collections import Counter
r = Counter(res)
print(r) # Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
print(r.get('a')) (按k取值) # 可以当成字典使用
time模块
常用方法
1.time.sleep(secs)
推迟指定的时间运行,单位为秒
ps:该方法贯穿前后(基础、后期)
2.time.time()
获取时间戳
#三种用于表示时间的格式(彼此之间可以转换)
1.时间戳
距离1970年1月1日0时0分0秒至此相差的秒数
time.time()
2.结构化时间
该时间类型主要是给计算机看的,人看起来不太方便
索引值(Index) | 属性(Attribute) | 值(Values) |
---|---|---|
0 | tm_year(年) | (例如:2015) |
1 | tm_mon(月) | 1 ~ 12 |
2 | tm_mday(日) | 1 ~ 31 |
3 | tm_hour(时) | 0 ~ 23 |
4 | tm_min(分) | 0 ~ 59 |
5 | tm_sec(秒) | 0 ~ 61(见下方注1) |
6 | tm_wday(星期几) | 0 ~ 6(0 表示星期一) |
7 | tm_yday(一年中的第几天) | 1 ~ 366 |
8 | tm_isdst(是否为夏令时) | 0, 1, -1(-1 代表夏令时) |
格式化时间:
人最容易接收的一种时间格式 2000/1/21 11:11:11
time.strftime()
'%Y-%m-%d %H:%M:%S' # 2022-03-29 11:31:30
'%Y-%m-%d %X' # 2022-03-29 11:31:30
格式化时间 |
---|
%y 两位数的年份表示(00-99) |
%Y 四位数的年份表示(000-9999) |
%m 月份(01-12) |
%d 月内中的一天(0-31) |
%H 24小时制小时数(0-23) |
%I 12小时制小时数(01-12) |
%M 分钟数(00=59) |
%S 秒(00-59) |
%a 本地简化星期名称 |
格式化时间 |
---|
%A 本地完整星期名称 |
%b 本地简化的月份名称 |
%B 本地完整的月份名称 |
%c 本地相应的日期表示和时间表示 |
%j 年内的一天(001-366) |
%p 本地A.M.或P.M.的等价符 |
%U 一年中的星期数(00-53)星期天为星期的开始 |
%w 星期(0-6),星期天为星期的开始 |
%W 一年中的星期数(00-53)星期一为星期的开始 |
格式化时间 |
---|
%x 本地相应的日期表示 |
%X 本地相应的时间表示 |
%Z 当前时区的名称 |
%% %号本身 |
各种模块的一个表格
namedtuple() |
创建命名元组子类的工厂函数 |
---|---|
deque |
类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop) |
ChainMap |
类似字典(dict)的容器类,将多个映射集合到一个视图里面 |
Counter |
字典的子类,提供了可哈希对象的计数功能 |
OrderedDict |
字典的子类,保存了他们被添加的顺序 |
defaultdict |
字典的子类,提供了一个工厂函数,为字典查询提供一个默认值 |
UserDict |
封装了字典对象,简化了字典子类化 |
UserList |
封装了列表对象,简化了列表子类化 |
UserString |
封装了字符串对象,简化了字符串子类化 |
时间类型的转换
格式化时间 <==> 结构化时间 <==> 时间戳
# 时间戳<-->结构化时间
gmtime
localtime
# 结构化时间<-->格式化时间
strftime
strptime
gmtime 断续器
localtime 本地时间
strftime 开始时间
strptime 停止时间
time.strptime("2017-03-16","%Y-%m-%d")
time.strptime("2017/03","%Y/%m") 前后必须一致
detetime模块
datetime 模块提供了各种类用于操作日期和时间,该模块侧重于高效率的格式化输出
基础的操作
import datetime
# print(datetime.date.today()) # 2022-03-29
# print(datetime.datetime.today()) # 2022-03-29 11:55:50.883392
"""
date 意思就是年月日
datetime 意思就是年月日 时分秒
today 意思是今天
ps:后期很多时间相关的操作都是跟date和time有关系
import datetime
res = datetime.date.today()
print(res.year) # 2022
print(res.month) # 3
print(res.day) # 29
print(res.weekday()) # 1 星期0-6
print(res.isoweekday()) # 2 星期1-7
year 年
month 月
day 日
weekday 星期0-6
英 /ˈwiːkdeɪ/ 美 /ˈwiːkdeɪ/
n. 平日,普通日;工作日
网络释义
工作日 周日 平日 星期名称
isoweekday 星期1-7
时间差
有很多时间选项(年月日)
import datetime
# res = datetime.date.today()
# print(res.year) # 2022
# print(res.month) # 3
# print(res.day) # 29
# print(res.weekday()) # 1 星期0-6
# print(res.isoweekday()) # 2 星期1-7
ctime = datetime.datetime.today()
time_tel = datetime.timedelta(days=2)
print(ctime)
print(ctime + time_tel)
针对时间计算的公式
日期对象 = 日期对象 +/- timedelta对象
timedelta对象 = 日期对象 +/- 日期对象
"""
res = ctime + time_tel
print(res - ctime)
2 days, 0:00:00
2 days, 0:00:00
random模块
随机数模块 (导入模块)
1.random.random()
返回[0, 1)范围内随机浮点数,不包括1
>>> random.random()
0.41385723239524297
# random模块
# print(random.uniform(1,4)) #随机产生一到四的小数不包括1,,4
# print(random.randint(1,9)) #随机产生1~9整数 包括1~9
l1=[1,2,3,4,5,6,7,8,9,10,11,12,13]
random.shuffle(l1)
print(l1)
# 随即发牌
l11=['aaa','bbbb','cccc','请鸡哥洗脚']
print(random.sample(l11,4)) #这个四要对应参数多了报错
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下