一、文件自动化处理&邮件批量处理
目录
来源
Datewhle26期__Python办公自动化 :
https://github.com/datawhalechina/team-learning-program/tree/master/OfficeAutomation
作者:牧小熊、刘雯静、张晓东、吴争光、隆军
论坛地址:
http://datawhale.club/t/topic/1574
1 文件自动化处理
1.1 文件的读写
- OS库: 是 python 标准库模块, 包含几百个函数,常用路径操作、进程管理、环境参数等几类。os.path子库以path为入口,用于操作和处理文件路径
import os
import os.path as op
-
op.abspath(path)
# 返回path在当前系统中的绝对路径
op.isabs(path)
:判断是否是绝对路径,是返回True,不是则返回False
op.normpath(path)
# 归一化path的表示形式,统一用\分隔路径
op.relpath(path)
# 返回当前程序与文件之间的相对路径 (relative path)
op.dirname(path)
# 返回path中的目录名称
op.basename(path)
# 返回path中当前的文件名称
op.join(path, *paths)
# 组合path与paths,返回一个路径字符串
op.exists(path)
# 判断path对应文件或文件夹是否存在,返回True或False
op.isfile(path)
# 判断path所对应是否为已存在的文件,返回True或False
op.isdir(path)
# 判断path所对应是否为已存在的文件夹,返回True或False
op.getatime(path)
# 返回path对应文件或目录上一次的访问时间
op.getmtime(path)
# 返回path对应文件或目录最近一次的修改时间
op.getctime(path)
# 返回path对应文件或目录的创建时间
op.getsize(path)
# 返回path对应文件的大小,以字节为单位 -
os.makedirs()
可以创建所有必要的中间文件夹
os.chdir(path)
# 修改当前程序操作的路径
os.getcwd()
# 返回程序的当前路径
os.getlogin()
# 获得当前系统登录用户名称
os.listdir(path)
:返回文件名字符串的列表,包含path参数中的每个文件。
- 读写步骤
open()
函数,返回一个File对象,打开 → 调用File对象的read()
或write()
方法 ,读写→ 调用File对象的close()
方法,关闭
open()
函数将会返回一个File对象read()
:读取文件内容;readlines()
:按行读取文件中的内容,取得一个字符串列表write()
方法不会像print()函数那样,在字符串的末尾自动添加换行字符。必须自己添加该字符。
练习1
1、如果已有的文件以写模式打开,会发生什么?
- 会覆盖已有文件
2、read()
和readlines()
方法之间的区别是什么?
read([size])
方法从文件当前位置起读取size个字节,若无参数size读取至文件结束为止,它范围为字符串对象readlines()
方法读取整个文件所有行,保存在一个列表(list)变量中,每行作为一个元素,但读取大文件会比较占内存。
综合练习:
一、生成随机的测验试卷文件
假如你是一位地理老师, 班上有 35 名学生, 你希望进行美国各州首府的一个
小测验。不妙的是,班里有几个坏蛋, 你无法确信学生不会作弊。你希望随机调整
问题的次序, 这样每份试卷都是独一无二的, 这让任何人都不能从其他人那里抄袭答案。当然,手工完成这件事又费时又无聊。 好在, 你懂一些 Python。
下面是程序所做的事:
• 创建 35 份不同的测验试卷。
• 为每份试卷创建 50 个多重选择题,次序随机。
• 为每个问题提供一个正确答案和 3 个随机的错误答案,次序随机。
• 将测验试卷写到 35 个文本文件中。
• 将答案写到 35 个文本文件中。
这意味着代码需要做下面的事:
• 将州和它们的首府保存在一个字典中。
• 针对测验文本文件和答案文本文件,调用 open()、 write()和 close()。
• 利用 random.shuffle()随机调整问题和多重选项的次序。
1.2 文件的调度
shutil
(或称为shell工具)模块中包含一些函数,可以在Python程序中复制、移动、改名和删除文件。要使用shutil
的函数,首先需要import shutil
import shutil
1.2.1 复制、移动、删除
shutil.copy(source, destination)
:将路径source处的文件复制到路径 destination处的文件夹(source 和 destination 都是字符串),并返回新复制文件绝对路径字符串。
其中destination
是:
1)、一个文件的名称,则将source文件复制为新名称的destination
2)、一个文件夹,则将source文件复制到destination中
3)、若这个文件夹不存在,则将source目标文件内的内容复制到destination中,若destination文件夹不存在,则自动生成该文件。(慎用,因为会将source文件复制为一个没有扩展名的名字为destination的文件,这往往不是我们希望的)
shutil.copytree(source, destination)
:将路径source处的文件夹,包括其包含的文件夹和文件,复制到路径destination处的文件夹,并返回新复制文件夹绝对路径字符串。
注:destination处的文件夹为新创建的文件夹,如已存在,则会报错
shutil.move(source, destination)
:将路径 source 处的文件/文件夹移动到路径destination,并返回新位置的绝对路径的字符串。
1)、如果source和destination是文件夹,且destination已存在,则会将source文件夹下所有内容复制到destination文件夹中。移动。
2)、如果source是文件夹,destination不存在,则会将source文件夹下所有内容复制到destination文件夹中,source原文件夹名称将被替换为destination文件夹名。 移动+重命名
3)、如果source和destination是文件,source处的文件将被移动到destination处的位置,并以destination处的文件名进行命名, 移动+重命名
注意:如果destination中有原来已经存在同名文件,移动后,会被覆写,所以应当特别注意。
os.unlink(path)
: 删除path处的文件。
os.rmdir(path)
: 删除path处的文件夹。该文件夹必须为空,其中没有任何文件和文件夹。
shutil.rmtree(path)
:删除 path 处的文件夹,它包含的所有文件和文件夹都会被删除。
注意:使用时,需要非常小心,避免删错文件,一般在第一次运行时,注释掉这些程序,并加上print()
函数来帮助查看是否是想要删除的文件。
shutil.rmtree(path)
会不可恢复的删除文件和文件夹,用起来会有危险。因此使用第三方的send2trash
模块,可以将文件或文件夹发送到计算机的垃圾箱或回收站,而不是永久删除。因程序缺陷而用send2trash 删除的某些你不想删除的东西,稍后可以从垃圾箱恢复。
注意:使用时,需要非常小心,避免删错文件,一般在第一次运行时,注释掉这些程序,并加上print()
函数来帮助查看是否是想要删除的文件。
1.2.2 遍历
os.walk(path)
:传入一个文件夹的路径,在for循环语句中使用os.walk()
函数,遍历目录树,和range()函数遍历一个范围的数字类似。不同的是,os.walk()
在循环的每次迭代中,返回三个值:
1)、当前文件夹称的字符串。
2)、当前文件夹中子文件夹的字符串的列表。
3)、当前文件夹中文件的字符串的列表。
注:当前文件夹,是指for循环当前迭代的文件夹。程序的当前工作目录,不会因为os.walk()
而改变。
- 创建ABCD文件夹
# 遍历A
import os
for folderName, subFolders,fileNames in os.walk('H:\\A'):
print('The current folder is ' + folderName)
for subFolder in subFolders:
print('Subfolder of ' + folderName+':'+subFolder)
for filename in fileNames:
print('File Inside ' + folderName+':'+filename)
print('')
1.2.3 压缩
1.创建压缩文件
zipfile.ZipFile('filename.zip', 'w')
:以写模式创建一个压缩文件
ZipFile
对象的 write('filename','compress_type=zipfile.ZIP_DEFLATED')
方法:
- 如果向
write()
方法中传入一个路径,Python 就会压缩该路径所指的文件, 将它加到 ZIP 文件中。 如果向write()
方法中传入一个字符串,代表要添加的文件名。
- 第二个参数是“压缩类型”参数,告诉计算机用怎样的算法来压缩文件。可以总是将这个值设置为
zipfile.ZIP_DEFLATED
(这指定了 deflate 压缩算法,它对各种类型的数据都很有效)。
注意:写模式会擦除zip文件中所有原有的内容。如果只希望将文件添加到原有的zip文件中,就要向zipfile.ZipFile()
传入’a’作为第二个参数,以添加模式打开 ZIP 文件。
import zipfile
newZip = zipfile.ZipFile('new.zip','w')
newZip.write('Miki.txt',compress_type=zipfile.ZIP_DEFLATED) #压缩文件名
newZip.close()
newZip = zipfile.ZipFile('new.zip','w')
newZip.write('D:\\animals\\dogs\\Taidi.txt',compress_type=zipfile.ZIP_DEFLATED)#压缩路径
newZip.close()
2.读压缩文件
调用zipfile.ZipFile(filename)
函数创建一个ZipFile
对象(注意大写字母Z和F),filename是要读取zip文件的文件名。
ZipFile
对象中的两个常用方法:
namelis()
方法,返回zip文件中包含的所有文件和文件夹的字符串列表。
getinfo()
方法,返回一个关于特定文件的ZipInfo
对象。
ZipInfo
对象的两个属性:file_size
和compress_size
,分别表示原来文件大小和压缩后文件大小。
import zipfile,os
exampleZip = zipfile.ZipFile('example.zip')
exampleZip.namelist()
3.解压
ZipFile
对象的 extractall()
方法:从zip文件中解压缩所有文件和文件夹,放到当前工作目录中。也可以向extractall()
传递的一个文件夹名称,它将文件解压缩到那个文件夹, 而不是当前工作目录。如果传递的文件夹名称不存在,就会被创建。
ZipFile
对象的 extract()
方法:从zip文件中解压单个文件。也可以向 extract()传递第二个参数, 将文件解压缩到指定的文件夹, 而不是当前工作目录。如果第二个参数指定的文件夹不存在, Python 就会创建它。extract()的返回值是被压缩后文件的绝对路径。
import zipfile, os
exampleZip = zipfile.ZipFile('example.zip')
exampleZip.extractall('.\zip')
exampleZip.close()
exampleZip = zipfile.ZipFile('example.zip')
exampleZip.extract('animals/Miki.txt')
exampleZip.extract('animals/Miki.txt', 'D:\\animals\\folders')
exampleZip.close()
练习2
1)、编写一个程序,遍历一个目录树,查找特定扩展名的文件(诸如.pdf 或.jpg)。不论这些文件的位置在哪里, 将它们拷贝到一个新的文件夹中。
- 假设遍历A中.txt文件
import os
def findTXT(target_dir, target_suffix="txt"):
global find_res
find_res = []
target_suffix_dot = "." + target_suffix
walk_generator = os.walk(target_dir)
for root_path, dirs, files in walk_generator:
if len(files) < 1:
continue
for file in files:
file_name, suffix_name = os.path.splitext(file)
if suffix_name == target_suffix_dot:
find_res.append(os.path.join(root_path, file))
return find_res
findTXT('H:\\A', target_suffix="txt")
有了TXT文件的路径, 然后复制即可
import shutil
for filepath in find_res:
shutil.copy(filepath,'E:\\A')
2) 、一些不需要的、 巨大的文件或文件夹占据了硬盘的空间, 这并不少见。如果你试图释放计算机上的空间, 那么删除不想要的巨大文件效果最好。但首先你必须找到它们。编写一个程序, 遍历一个目录树, 查找特别大的文件或文件夹, 比方说, 超过100MB 的文件(回忆一下,要获得文件的大小,可以使用 os 模块的 os.path.getsize()
)。将这些文件的绝对路径打印到屏幕上。
import os
def find100MB(target_dir):
find_res = []
walk_generator = os.walk(target_dir)
for root_path, dirs, files in walk_generator:
if len(files) < 1:
continue
for file in files:
if os.path.getsize() >= 1024*1024*100:
find_res.append(os.path.join(root_path, file))
return find_res
find100MB('H:\\A')
3)、编写一个程序, 在一个文件夹中, 找到所有带指定前缀的文件, 诸如 spam001.txt,spam002.txt 等,并定位缺失的编号(例如存在 spam001.txt 和 spam003.txt, 但不存在 spam002.txt)。让该程序对所有后面的文件改名, 消除缺失的编号。作为附加的挑战,编写另一个程序,在一些连续编号的文件中,空出一些编号,以便加入新的文件。
1.2 自动发送电子邮件
使用Python实现自动化邮件发送,可以让你摆脱繁琐的重复性业务,节省非常多的时间。
Python有两个内置库:smtplib
和email
,能够实现邮件功能,smtplib
库负责发送邮件,email
库负责构造邮件格式和内容。
邮件发送需要遵守SMTP协议,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。
#1 先导入相关的库和方法
import smtplib #导入库
from smtplib import SMTP_SSL #加密邮件内容,防止中途被截获
from email.mime.text import MIMEText #构造邮件的正文
from email.mime.image import MIMEImage #构造邮件的图片
from email.mime.multipart import MIMEMultipart #把邮件的各个部分装在一起,邮件的主体
from email.header import Header #邮件的文件头,标题,收件人
#2 设置邮箱域名、发件人邮箱、邮箱授权码、收件人邮箱
host_server = 'smtp.163.com' #sina 邮箱smtp服务器 #smtp 服务器的地址
sender_163 = 'pythonauto_emai@163.com' #sender_163为发件人的邮箱
pwd = 'DYEPOGLZDZYLOMRI' #pwd为邮箱的授权码'DYEPOGLZDZYLOMRI'
#也可以自己注册个邮箱,邮箱授权码'DYEPOGLZDZYLOMRI' 获取方式可参考#http://help.163.com/14/0923/22/A6S1FMJD00754KNP.html
receiver = '********@163.com'
#3 构建MIMEMultipart对象代表邮件本身,可以往里面添加文本、图片、附件等
msg = MIMEMultipart() #邮件主体
#4 设置邮件头部内容
mail_title = 'python办公自动化邮件' # 邮件标题
msg["Subject"] = Header(mail_title,'utf-8') #装入主体
msg["From"] = sender_163 #寄件人
msg["To"] = Header("测试邮箱",'utf-8') #标题
#5 添加正文文本
mail_content = "您好,这是使用python登录163邮箱发送邮件的测试" #邮件的正文内容
message_text = MIMEText(mail_content,'plain','utf-8') #构造文本,参数1:正文内容,参数2:文本格式,参数3:编码方式
msg.attach(message_text) # 向MIMEMultipart对象中添加文本对象
#6 添加图片
image_data = open('cat.jpg','rb') # 二进制读取图片
message_image = MIMEImage(image_data.read()) # 设置读取获取的二进制数据
image_data.close() # 关闭刚才打开的文件
msg.attach(message_image) # 添加图片文件到邮件信息当中去
# 7 添加附件(excel表格)
atta = MIMEText(open('cat.xlsx', 'rb').read(), 'base64', 'utf-8') # 构造附件
atta["Content-Disposition"] = 'attachment; filename="cat.xlsx"' # 设置附件信息
msg.attach(atta) ## 添加附件到邮件信息当中去
#8 发送邮件
smtp = SMTP_SSL(host_server) #SSL登录 创建SMTP对象
smtp.login(sender_163,pwd) ## 登录邮箱,传递参数1:邮箱地址,参数2:邮箱授权码
smtp.sendmail(sender_163,receiver,msg.as_string()) # 发送邮件,传递参数1:发件人邮箱地址,参数2:收件人邮箱地址,参数3:把邮件内容格式改为str
print("邮件发送成功")
smtp.quit # 关闭SMTP对象
参考资料
- https://www.cnblogs.com/Lengjie/p/9391390.html os库(python)—总结 - todaynowind