Python 压缩文件夹并发送邮件功能
1. 功能概述
本笔记介绍如何使用 Python 进行以下操作:
- 将指定文件夹中的文件压缩为
.zip
文件,不包含子文件夹及其内容。 - 将压缩后的文件通过电子邮件发送给指定收件人,使用 QQ 邮箱作为发送邮件的 SMTP 服务器。
2. 将文件夹压缩为 ZIP 文件(不含子文件夹)
代码:
import os
import zipfiledef zip_folder(folder_path: str, output_path: str) -> None:"""将指定文件夹中的文件压缩为 zip 文件,不包含子文件夹及其内容:param folder_path: 要压缩的文件夹路径 (str):param output_path: 压缩文件保存路径 (str):return: None"""# 使用 'w' 模式打开 zip 文件,表示创建一个新的 zip 文件并写入内容with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf:# 遍历指定文件夹中的所有文件,不包括子文件夹for file in os.listdir(folder_path):file_path = os.path.join(folder_path, file)# 仅处理文件(忽略子文件夹)if os.path.isfile(file_path):# 将文件添加到 zip 文件中zipf.write(file_path, arcname=file) # arcname=file 使压缩包内文件保持原文件名# 输出压缩成功信息print(f"文件夹中的文件已压缩为:{output_path}")
代码解释:
os.listdir(folder_path)
:列出文件夹中的所有文件和子文件夹。os.path.isfile(file_path)
:检查文件路径是否为文件,忽略子文件夹。zipfile.ZipFile
:创建并写入 zip 文件,arcname=file
确保压缩包中的文件没有包含文件夹路径。
3. 通过邮件发送压缩文件
代码:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encodersclass FolderZipperAndEmailSender:def __init__(self, smtp_server: str, smtp_port: int, sender_email: str, sender_password: str):"""初始化邮件发送器:param smtp_server: SMTP 服务器地址:param smtp_port: SMTP 端口号:param sender_email: 发送方邮箱:param sender_password: 授权码(非邮箱密码)"""self.smtp_server = smtp_serverself.smtp_port = smtp_portself.sender_email = sender_emailself.sender_password = sender_passworddef send_email(self, recipient_email: str, subject: str, body: str, attachment_path: str) -> None:"""发送带附件的邮件:param recipient_email: 接收方邮箱:param subject: 邮件主题:param body: 邮件正文:param attachment_path: 附件路径:return: None"""# 创建邮件对象msg = MIMEMultipart()msg['From'] = self.sender_emailmsg['To'] = recipient_emailmsg['Subject'] = subject# 添加邮件正文msg.attach(MIMEText(body, 'plain'))# 添加附件with open(attachment_path, 'rb') as attachment:part = MIMEBase('application', 'octet-stream')part.set_payload(attachment.read())encoders.encode_base64(part)part.add_header('Content-Disposition',f'attachment; filename={os.path.basename(attachment_path)}')msg.attach(part)# 发送邮件 (好像用with邮件发送成功但会报错)with smtplib.SMTP_SSL(self.smtp_server, self.smtp_port) as server: # 使用 SSLserver.login(self.sender_email, self.sender_password)server.send_message(msg)print("邮件已发送")
代码解释:
- 邮件发送类
FolderZipperAndEmailSender
:该类负责发送邮件。需要提供 SMTP 配置、发送者邮箱和授权码。 send_email
方法:负责构建并发送邮件,支持正文和附件。使用MIMEText
和MIMEBase
构建邮件内容。- SMTP 配置:
- 使用 QQ 邮箱的 SMTP 服务器 (
smtp.qq.com
)。 - 使用 SSL 连接(端口 465)确保安全通信。
- 登录时使用授权码而不是邮箱密码。
- 使用 QQ 邮箱的 SMTP 服务器 (
4. 整合成完整的工作流程
整合代码:
import os
import zipfile
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encodersclass FolderZipperAndEmailSender:def __init__(self, smtp_server: str, smtp_port: int, sender_email: str, sender_password: str):"""初始化邮件发送器:param smtp_server: SMTP 服务器地址:param smtp_port: SMTP 端口号:param sender_email: 发送方邮箱:param sender_password: 授权码(非邮箱密码)"""self.smtp_server = smtp_serverself.smtp_port = smtp_portself.sender_email = sender_emailself.sender_password = sender_passworddef zip_folder(self, folder_path: str, output_path: str) -> None:"""将指定文件夹中的文件压缩为 zip 文件,不包含子文件夹及其内容:param folder_path: 要压缩的文件夹路径 (str):param output_path: 压缩文件保存路径 (str):return: None"""with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf:for file in os.listdir(folder_path):file_path = os.path.join(folder_path, file)if os.path.isfile(file_path):zipf.write(file_path, arcname=file)print(f"文件夹中的文件已压缩为:{output_path}")def send_email(self, recipient_email: str, subject: str, body: str, attachment_path: str) -> None:"""发送带附件的邮件:param recipient_email: 接收方邮箱:param subject: 邮件主题:param body: 邮件正文:param attachment_path: 附件路径:return: None"""msg = MIMEMultipart()msg['From'] = self.sender_emailmsg['To'] = recipient_emailmsg['Subject'] = subjectmsg.attach(MIMEText(body, 'plain'))with open(attachment_path, 'rb') as attachment:part = MIMEBase('application', 'octet-stream')part.set_payload(attachment.read())encoders.encode_base64(part)part.add_header('Content-Disposition', f'attachment; filename={os.path.basename(attachment_path)}')msg.attach(part)with smtplib.SMTP_SSL(self.smtp_server, self.smtp_port) as server:server.login(self.sender_email, self.sender_password)server.send_message(msg)print("邮件已发送")# 使用示例
if __name__ == "__main__":sender = FolderZipperAndEmailSender(smtp_server="smtp.qq.com",smtp_port=465,sender_email="your_email@qq.com",sender_password="your_authorization_code")folder_to_zip = "./example_folder"zip_file_path = "./example_folder.zip"# 压缩文件夹sender.zip_folder(folder_to_zip, zip_file_path)recipient_email = "recipient_email@example.com"subject = "压缩文件发送示例"body = "请查收附件中的压缩文件。"# 发送邮件sender.send_email(recipient_email, subject, body, zip_file_path)
5. 总结
通过以上的代码,我们实现了以下功能:
- 压缩文件夹:只压缩指定文件夹中的文件,不包括子文件夹。
- 发送邮件:通过 QQ 邮箱发送带附件的邮件。使用授权码代替密码,并使用 SSL 连接保证安全性。
这个工作流程可以帮助我们方便地将文件夹中的内容压缩并通过邮件发送,适用于批量文件传输和自动化任务。