各种模块讲解day15
今日学习总结:
模块
一、time 模块
在python的三种时间表现形式:
1.时间戳:给电脑看的
自1970-01-01 00:00:00到当前时间,按秒计算,计算了多少秒
2.格式化时间:(format string):给人看的
返回的是时间的字符串 2002-01-11
01将获取当前的时间对象进行格式化时间输出
import time
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())) #将获取当前的时间对象进行格式化时间输出 结果:2019-11-16 14:33:00
02把字符串格式的时间转为时间对象 .strptime
import time
res = time.strptime('2019-01-01', '%Y-%m-%d') #把字符串格式的时间转为时间对象 print(res) 结果: time.struct_time(tm_year=2019, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=1, tm_isdst=-1)
3.格式化时间对象(struct_time)
返回一个元组,元组中有9个人值:分别代表:年、月、日、时、分、秒、一周中的第几天、一年中的第几天、夏令时
1. .time()
import time print(time.time()) #获取时间戳
结果:
1573884986.1575663
2. .strftime()
注意:
%X 等于 %H:%M:%S
import time # 获取年月日时分秒 print(time.strftime('%Y-%m-%d %H:%M:%S')) # %X == %H:%M:%S print(time.strftime('%Y-%m-%d %X')
结果:
2019-11-16 14:20:24
2019-11-16 14:20:24
3. .localtime()
import time #获取时间对象 (****) print(time.localtime()) #获取当地的时间对象 是一个元组,包含了9个值 print(type(time.localtime())) #输出的结果是一个时间对象 time_obj = time.localtime() #将时间对象赋给一个变量 print(time_obj.tm_year) #取时间对象中的年的值 print(time_obj.tm_mon) #取时间对象中的月的值 结果: time.struct_time(tm_year=2019, tm_mon=11, tm_mday=16, tm_hour=14, tm_min=26, tm_sec=41, tm_wday=5, tm_yday=320, tm_isdst=0) <class 'time.struct_time'> 2019 11
4.
import time
res = time.localtime() #表示在睡之前获取时间对象 time.sleep(5) 获取当前时间的格式化时间 print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())) #这里的time.localtime() 表示在睡之后获取当前时间对象
将时间对象转为格式化时间
print(time.strftime('%Y-%m-%d %H:%M:%S', res))
结果:
2019-11-16 14:53:14
2019-11-16 14:53:09
二、datetime 模块
常用的方法:
1、.date.today() #获取当前年月日
2、.datetime.today() # 获取当前年月日时分秒
3、.datetime.now() #获取当前北京时间
4、.datetime.utnow() #获取当前北京时间
5、.timedelta(days=某个数字) #表示获取时间对象
例子:1和2
import datetime print(datetime.date.today()) #获取当前年月日 print(datetime.datetime.today()) # 获取当前年月日时分秒 time=datetime.date.today() #表示是一个时间对象 time_obj = datetime.datetime.today() #表示是一个时间对象 print(type(time_obj)) print(type(time_obj)) print(time_obj.year) print(time_obj.month) print(time_obj.day) 结果: 2019-11-16 2019-11-16 15:15:37.908715 <class 'datetime.datetime'> <class 'datetime.datetime'> 2019 11 16
例子:3和4
import datetime #UTC时区 print(datetime.datetime.now()) #获取当前北京时间 print(datetime.datetime.utcnow()) #获取当前格林威治时间 结果: 2019-11-16 15:21:29.314814 2019-11-16 07:21:29.314814
例子:5
# 时间对象 time_obj = datetime.timedelta(days=7) #表示获取7天时间 print(time_obj)
#日期/时间的计算 (*******) #日期时间 = 日期时间 “+” or “-” 时间对象 #时间对象 = 日期时间 “+” or “-” 日期时间 # 日期时间: import datetime current_time = datetime.datetime.now() #表示当前时间 print(current_time) # 时间对象 time_obj = datetime.timedelta(days=7) #表示获取7天时间 print(time_obj) later_time = current_time + time_obj # 获取当前时间7天后的时间:日期时间 = 日期时间 “+” or “-” 时间对象 print(later_time) time_new_obj = later_time - current_time # 时间对象 = 日期时间 “+” or “-” 日期时间 print(time_new_obj)
结果:
2019-11-16 15:38:37.719635
7 days, 0:00:00
2019-11-23 15:38:37.719635
7 days, 0:00:00
三、random模块
常用的内置方法:
1、.randint(a.b) 表示 生成一个[a,b]之间的随机整数
2、.uniform(a,b) 表示 生成一个[a,b]之间的随机小数
3、.random() 表示 默认获取0——1之间任意小数 ()中不写值
4、.choice(可迭代对象--这里的可迭代对象要有索引的 ) 表示从中随机选择一个元素
5、.shuffle(可迭代对象--注意不可变数据类型不行) 表示将所有的元素进行随机排序,返回打乱后的序列
6、.sample(list,k) 表示在list中随机产生一个长度为k的新列表
7、.seed() 表示初始化给的随机种子,默认为当前系统时间
8. chr(97) 表示可以将ASCII表中值转换成对应的字符
案例:需求:
大小写字母、数字组合而成
组合5位数的随机验证码
import random code='' #先定义一个空的字符串 for i in range(5): res1=random.randint(97,122) lower_str=chr(res1) res2=random.randint(65,90) upper_str=chr(res2) number=random.randint(0,9) number_str=str(number) #将随机取出的整数转换成字符串 code_list=[lower_str,upper_str,number_str] #表示把每一次随机产生的lower_str upper_str number_str 放到code_list列表里 random_code=random.choice(code_list) code +=random_code #for i in range(5) 表示code会加5次 所以才出现5位的验证码 print(code) 结果: T1s15 随机的 不定的
优化:让验证码可以任意位
import random def get_code(n): code='' for i in range(n): res1=random.randint(97,122) lower_str=chr(res1) res2=random.randint(65,90) upper_str=chr(res2) number=random.randint(0,9) number_str=str(number) #将随机取出的整数转换成字符串 code_list=[lower_str,upper_str,number_str] #表示把每一次随机产生的lower_str upper_str number_str 放到code_list列表里 random_code=random.choice(code_list) code +=random_code #for i in range(5) 表示code会加5次 所以才出现5位的验证码 return code get_code=get_code(7) print(get_code) #在这里不能用get_code 因为返回的code 是字符串
函数地址作返回值
def test3(u): print(f"{u}hello") return test3 #test3是个地址,返回给函数test3() .注意test3() 也是一个地址,因为test3是个地址给了test3() z=test3(2) #函数被调用了一次,并把返回的函数地址给了变量z z(3) #这里变量z是地址 加上()又调用函数了
def test3(u): print(f"{u}hello") return test3 #test3是个地址,返回给函数test3() .注意test3() 也是一个地址,因为test3是个地址给了test3() z=test3(2) #函数被调用了一次,并把返回的函数地址给了变量z z(3) #这里变量z是地址 加上()又调用函数了
结果:
2hello
3hello
四、os 模块:是与操作系统交互的模块
注意:项目的根目录,路径相关的值都用 “常量
常用方法:
1、.path.dirname(_file_) 表示获取当前文件的上一级目录路径
2、.path.join(绝对路径,要拼接的文件的名字) 表示路径拼接,拼接文件 “绝对路径”
3、.path.exists(文件名/文件夹/绝对路径) 表示查看文件名/文件夹是否存在,返回的是一个布尔值
4、 .path.isdir(文件夹的路径) 表示查看文件夹是否存在
5、 .path.isfile(文件的路径) 表示查看文件是否存在
6、.mkdir(文件名/文件夹) 表示创建文件名/文件夹
7、.rmdir(文件名/文件夹) 表示删除文件名/文件夹 (注意:只能删除空的)
8、.listdir(r'文件夹的绝对路径') 表示取某个文件夹中所有文件的名字
08、 enumerate(可迭代对象) ---> 得到一个对象,对象有一个个的元组(索引, 元素)
例子1
ps:DAY15_PATH 表示是当前文件 import os DAY15_PATH = os.path.dirname(__file__) print(DAY15_PATH)
例子6和06
import os teacher_list = os.listdir(r'G:\正课\day15') # .listdir()表示 将某个文件夹下的所有文件取出文件名,返回的是一个列表。 print(teacher_list) res = enumerate(teacher_list) #enumerate(可迭代对象) 表示将可迭代对象返回一个里面有一个个元组(这个元组带编号,格式是(0,元素),(1,元素)。。。)组成的元组 print(list(res)) # 让用户选择文件 while True: # 1.打印所有老师的作品 for index, name in enumerate(teacher_list): print(f'编号: {index} 文件名: {name}') choice = input('请选择想看的老师作品编号:').strip() # 2.限制用户必须输入数字,数字的范围必须在编号内 # 若不是数字,则重新选择 if not choice.isdigit(): print('必须输入数字') continue # 若是数字,往下走判断是否在编号范围内 choice = int(choice) # 判断如果不在列表范围内,则重新选择 if choice not in range(len(teacher_list)): print('编号范围错误!') continue file_name = teacher_list[choice] #teacher_list是一个列表,choice是索引值 teacher_path = os.path.join(r'G:\正课\day15', file_name) #拼接路径 print(teacher_path) with open(teacher_path, 'r', encoding='utf-8') as f: print(f.read())
五、 sys 模块:与python交互
例子要看
方法:
sys.path
sys.path.append(项目路径)
import sys import os print(sys.path) # 获取当前的Python解释器的环境变量路径,获得一个列表,里面有一堆路径 BASE_PATH = os.path.dirname(os.path.dirname(__file__)) #将当前项目添加到环境变量中 sys.path.append(BASE_PATH) 将挡墙项目根目录添加到环境变量中。 # 获取操作系统cmd终端的命令行 python3 py文件 用户名 密码 print(sys.argv) # 返回的是列表[''] sys.argv 表示执行py文件的权限认证
六、hashlib :是一个加密模块:
内置了很多算法
1- MD5: 不可解密的算法(2018年以前)
hashlib.md5() 获取对象
hashlib.md5().update(密码.encode('utf-8'))
hashlib.md5().hexdigest()
import hashlib md5_obj = hashlib.md5() # MD5: 不可解密的算法 在这里.md5()是一类对象 print(type(md5_obj)) str1 = '1234' md5_obj.update(str1.encode('utf-8')) # update中一定要传入bytes类型数据 在这里将字符串str1解码成二进制 res = md5_obj.hexdigest() # 得到一个加密后的字符串 print(res)
结果:
<class '_hashlib.HASH'>
81dc9bdb52d04dc20036dbd8313ed055
2-摘要算法:
- 摘要是从某个内容中获取的加密字符串
- 摘要一样,内容就一定一样: 保证唯一性
- 密文密码就是一个摘要
七、序列化模块:也是字符串化,将其他数据类型转成字符串再存到文件中
1. json模块:提供了一种很简单的方式来编码和解码JSON数据。是一个序列化模块,一个第三方的特殊数据格式。可以将python数据类型---json数据格式---字符串---文件中
其他语言想要使用python的数据:文件中---字符串---json数据格式---其他语言的数据类型
ps:
# 在json中,所有的字符串都是双引号
# 元组比较特殊:python中的元组,若将其转换成json数据,内部会将元组 ---> 列表
# set是不能转换成json数据
内置的方法:
01、 json.dumps(list/dict/tuple,ensure_ascii=False) 用于将list/dict/tuple类型的数据转成str,因为如果直接将dict类型的数据写入json文件中会发生报错,因此在将数据写入时需要用到该函数。
02、json.loads() 用于将str类型的数据转成dict。
03、json.dump() 用于将dict类型的数据转成str,并写入到json文件中。
04、json.load() 用于从json文件中读取数据。
例子01和02
import json list1 = ['张全蛋', '李小花'] json_str = json.dumps(list1, ensure_ascii=False) # ensure_ascii将默认的ascii .取消设置为False,可以在控制台看到中文,否则看到的是bytes类型数据 print(json_str) print(type(json_str)) # str python_data=json.loads(json_str) print(python_data) print(type(python_data)) # list 结果: ["张全蛋", "李小花"] <class 'str'> ['张全蛋', '李小花'] <class 'list'>
元组比较特殊:python中的元组,若将其转换成json数据,内部会将元组 ---> 列表
tuple1 = ('张全蛋', '李小花') json_str = json.dumps(tuple1, ensure_ascii=False) print(json_str) #这里将元组转成列表,再变成json数据类型的str 因为元组本身不可变,存数据是为了读改数据 print(type(json_str)) # str python_data = json.loads(json_str) print(tuple(python_data)) print(type(tuple(python_data))) # list
结果:
["张全蛋", "李小花"] #这里本来应该是 () 现在是[]
<class 'str'>
('张全蛋', '李小花')
<class 'tuple'>
PS: 由于各种语言的数据类型不一,但长相可以一样,
比如python不能直接使用其他语言的数据类型,
必须将其他语言的数据类型转换成json数据格式,
python获取到json数据后可以将json转换成python的数据类型。
loads 与load 的区别
1.loads
loads针对内存对象
loads: 将 字符串 转换为 字典
2.load
load针对文件句柄
load: 将数据写入json文件中
import json dic = { 'name': 'tank', 'age': 17 } json_str = json.dumps(dic, ensure_ascii=False) print(json_str) print(type(json_str)) # str python_data = json.loads(json_str) print(python_data) print(type(python_data)) # dict
结果:
{"name": "tank", "age": 17} #这里 看起来像字典,但是它是json数据类型,是字符串。
<class 'str'>
{'name': 'tank', 'age': 17}
<class 'dict'>
案例:json.dumps和json.loads存取数据
import json def register(): username = input('请输入用户名:').strip() password = input('请输入密码:').strip() re_password = input('请确认密码:').strip() if password == re_password: user_dic = { 'name': username, 'pwd': password } json_str = json.dumps(user_dic, ensure_ascii=False) #用json.dumps转化成json数据类型 # 注意: 保存json数据时,用.json作为文件的后缀名 with open('user.json', 'w', encoding='utf-8') as f: f.write(json_str) else: print('输入的密码不一致')
with open('user.json', 'r', encoding='utf-8') as f:
res=json.loads(f.read())
print(res)
register()
案例:用json.dump和json.load存取数据
import json def register(): username = input('请输入用户名:').strip() password = input('请输入密码:').strip() re_password = input('请确认密码:').strip() if password == re_password: user_dic = { 'name':username, 'pwd': password } with open('user1.json', 'w', encoding='utf-8') as f: json.dump(user_dic, f) #将字典里的数据转成json数据 with open('user1.json', 'r', encoding='utf-8') as f: user_dic = json.load(f) #将文件里的json数据转成字典 print(user_dic) print(type(user_dic)) # dict register()
2、pickle模块:是一个python自带的序列化模块。
方法:
pickle.dump(字典/list/tuple/str,句柄)
pickle.load(句柄)
优点:
- 可以支持python中所有的数据类型
- 可以直接存 "bytes类型" 的数据,pickle存取速度更快
缺点: (致命的缺点)
- 只能支持python去使用,不能跨平台
import pickle set1 = { 'tank', 'sean', 'jason', '大脸' } # 写 dump with open('teacher.pickle', 'wb') as f: pickle.dump(set1, f) #以字节的形式写入文件 # 读 load with open('teacher.pickle', 'rb') as f: python_set = pickle.load(f) #从文件里读出来字节时,用load转成了python数据类型 print(python_set) print(type(python_set))
八、collections模块:提供一些python八大数据类型 “以外的数据类型” 。
1、collections模块下的 具名元组( namedtuple):具名元组 只是一个名字。
from collections import namedtuple
应用一:扑克牌
from collections import namedtuple card = namedtuple('扑克牌', ['color', 'number']) #获取扑克牌对象 red_A = card('♥', 'A') print(red_A) black_K = card('♠', 'K') print(black_K) 结果: 扑克牌(color='♥', number='A') 扑克牌(color='♠', number='K')
应用二:坐标,传入可迭代对象是有序的 from collections import namedtuple point = namedtuple('坐标', ['x', 'y']) # 第二个参数既可以传可迭代对象 point1 = namedtuple('坐标', ('x', 'y')) # 第二个参数既可以传可迭代对象 point2 = namedtuple('坐标', 'x y') # 第二个参数既可以传可迭代对象 p = point(1, 3) # 本质上传了3个,面向对象讲解,#传参的个数,要与namedtuple第二个参数的个数一一对应
print(p.x) # 1 ?
print(p.y) # 3 ?
p1=point(4,7)
p2=point(5,6)
print(p,p1,p2)
print(type(p))
结果:
坐标(x=1, y=3) 坐标(x=4, y=7) 坐标(x=5, y=6)
<class '__main__.坐标'>
2、collections模块下的 有序字典(OrderedDict):python中字典默认是无序,collections中提供了有序的字典. 有序字典是无序字典派生而来,有无序字典的方法
from collections import OrderedDict
方法: OrderedDict(无序的字典)
from collections import OrderedDict order_dict = OrderedDict({'x': 1, 'y': 2, 'z': 3}) print(order_dict) print(type(order_dict)) print(order_dict.get('y')) #表示取键y 所对应的值 print(order_dict['z']) #表示取键z 所对应的值 print(type(order_dict)) for line in order_dict: #表示遍历的是字典order_dic的key print(line) #输出的key 是有序的,只是这个字典的数据太小,看不出来而已
结果:
OrderedDict([('x', 1), ('y', 2), ('z', 3)])
2
3
<class 'collections.OrderedDict'>
x
y
z
dic = dict({'x': 1, 'y': 2, 'z': 3}) print(dic) print(dic.get('y')) #表示取键y 所对应的值 print(dic['z']) #表示取键z 所对应的值 print(type(dic)) for line in dic: #表示遍历的是字典dic的key print(line) #输出的key 是无序的,只是这个字典的数据太小,看不出来而已
结果:
{'x': 1, 'y': 2, 'z': 3}
2
3
<class 'dict'>
x
y
z
九、openpyxl模块:第三方模块。可以对Excle表格进行操作的模块
1.openpyxl模块下的 Workbook
方法:Workbook() 是excel文件对象
Workbook().create_sheet('写工作表的名字')
Workbook().save('写excel的名字.xlsx')
from openpyxl import Workbook wb_obj = Workbook() # 获取Excel文件对象 wb1 = wb_obj.create_sheet('序列化1') #创建一个工作表 wb2 = wb_obj.create_sheet('序列化2') #创建一个工作表 print(wb1.title) wb1.title = '大宝贝' print(wb1.title) wb_obj.save('序列化。xlsx') # 生成Excel表格 print('excel表格生成成功')
案例:写100个数据
from openpyxl import Workbook wb_obj = Workbook() wb1 = wb_obj.create_sheet('工作表1') n = 1 for line in range(100): wb1['A%s' % n] = line + 1 # wb1['表格位置'] = 对应的值 A%s 表示表中A列 % n 表示第几行 line + 1 表示要填的值 n += 1 wb_obj.save('100条数据.xlsx')
案例2:写多个字典数据到表里
from openpyxl import Workbook wb_obj=Workbook() wb1=wb_obj.create_sheet('表格1') dict1 = { 'name': 'tank', 'age': 17 } n = 1 for key, value in dict1.items(): #dict1.items() 表示返回一个包含所有(键,值)元组的 列表 wb1['A%s' % n] = key wb1['B%s' % n] = value n += 1 wb_obj.save('批量插入数据.xlsx')
2.openpyxl模块下的load_workbook
from openpyxl import load_workbook wb_obj = load_workbook('序列化.xlsx') #读取excel表里的数据 print(wb_obj) wb1 = wb_obj['序列化2'] # wb_obj['表名'] print(wb1['A10'].value) #取序列化2工作表中 A10的值 wb1['A10'] = 20 #将序列化2工作表中 A10的值 改成20 print(wb1['A10'].value)
wb_obj.save('序列化.xlsx') #保存修改后的excel表
十、requests模块:第三方模块
方法:
01、 requests.get('网址') 得到一个响应response
02、requests.get('网址').content 得到一个二进制数据
03、requests.get('网址').iter_content() 得到一个生成器对象
04、 requests.get('网址').status_code 得到一个状态码
import requests response = requests.get('https://gss3.bdstatic.com/7Po3dSag_xI4khGkpoWK1HF6hhy/baike/w%3D268%3Bg%3D0/sign=9e8b07a25782b2b7a79f3ec20996acd2/aa64034f78f0f736900cd3a70455b319eac413a1.jpg') print(response.content) print(response.iter_content()) with open('小泽泽2.jpg', 'wb') as f: for line in response.iter_content(): f.write(line)
案例:爬取250个电影信息
''' 爬取豆瓣TOP250电影信息 第1页: https://movie.douban.com/top250?start=0&filter= ... 第9页: https://movie.douban.com/top250?start=200&filter= 第10页: https://movie.douban.com/top250?start=225&filter= ''' import requests import re # 1.发送请求 def get_page(url): response = requests.get(url) # response.content # 获取二进制流数据,比如图片、视频、音频 # response.text # 获取响应文本,比如html代码 return response # 2.解析数据 # response = get_page('url地址') # parser_page(response.text) def parser_page(text): # response.text res_list = re.findall( '<div class="item">.*?<a href="(.*?)">.*?<span class="title">(.*?)</span>.*?<span class="rating_num".*?>(.*?)</span>.*?<span>(.*?)人评价', text, re.S) #re.S 使用re.S参数以后,正则表达式会将这个文本里的数据/字符串作为一个整体,在整体中进行匹配。 for movie_tuple in res_list: print(movie_tuple) yield movie_tuple #yield是生成器,生成movie_tuple # 3.保存数据 # res_list = parser_page(text) # save_data(res_list) def save_data(res_list_iter): with open('douban.txt', 'a', encoding='utf-8') as f: for movie_tuple in res_list_iter: movie_url, movie_name, movie_point, movie_num = movie_tuple #解压赋值 str1 = f''' 电影地址: {movie_url} 电影名字: {movie_name} 电影评分: {movie_point} 评价人数: {movie_num} ''' f.write(str1) # 获取10个链接 n = 0 for line in range(10): url = f'https://movie.douban.com/top250?start={n}&filter=' n += 25 response = get_page(url) res_list_iter = parser_page(response.text) # print(res_list_iter) save_data(res_list_iter)
异步爬取梨视频
# 异步爬取梨视频 import requests import re import os import uuid from concurrent.futures import ThreadPoolExecutor pool = ThreadPoolExecutor(100) # 1.发送请求,获取响应数据 def get_page(url): print(f'发送get请求: {url}') response = requests.get(url) if response.status_code == 200: return response # 2.解析并提取主页id号 def parse_page(response): ''' https://www.pearvideo.com/video_1630253 https://www.pearvideo.com/video_1630042 ''' # 将所有电影的详情页id号,匹配获取,并放到列表中 id_list = re.findall('href="video_(.*?)"', response.text, re.S) # print(len(id_list)) id_list = list(set(id_list)) # print(len(id_list)) return id_list # 解析详情页,获取视频链接 def parse_detail(res): # parse_detail函数接收的是一个对象, ''' srcUrl="https://video.pearvideo.com/mp4/adshort/20191206/cont-1630253-14671892_adpkg-ad_hd.mp4" srcUrl="(.*?)" ''' res2 = res.result() print(res2) movie_url = re.findall('srcUrl="(.*?)"', res2.text, re.S) print(movie_url) if movie_url: movie_url = movie_url[0] pool.submit(save_movie, movie_url) # 3.保存数据 def save_movie(movie_url): # time.sleep(1) # 获取响应数据的过程是IO操作 response = requests.get(movie_url) movie_dir = r'G:\正课\进程与线程\梨视频文件夹' movie_path = os.path.join( movie_dir, str(uuid.uuid4()) + '.mp4' ) # print(movie_path) with open(movie_path, 'wb') as f: for line in response.iter_content(): f.write(line) if __name__ == '__main__': response = get_page('https://www.pearvideo.com/') id_list = parse_page(response) for id_num in id_list: # 每一个视频详情页 url = f'https://www.pearvideo.com/video_{id_num}' # 异步提交并爬取详情页任务
# add_done_callback(函数名) 表示的是回调函数
# add_done_callback(parse_detail): 将get_page任务结束后的结果,立马扔给parse_detail函数。实现一边下载数据一边解析数据 # parse_detail函数接收的是一个对象,对象中的result()就是get_page函数的返回值。 pool.submit(get_page, url).add_done_callback(parse_detail) import datetime print(datetime.datetime.now()) # 21:54 ---> 18:45

浙公网安备 33010602011771号