Python邮件附件案例如何添加邮件附件

wen python案例 26

本文目录导读:

Python邮件附件案例如何添加邮件附件

  1. 基础邮件附件示例
  2. 注意事项

我来为您介绍Python发送邮件附件的完整案例,使用内置的smtplibemail库。

基础邮件附件示例

单附件发送

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import os
def send_email_with_attachment(sender_email, sender_password, receiver_email, 
                                subject, body, file_path):
    """
    发送带附件的邮件
    :param sender_email: 发件人邮箱
    :param sender_password: 发件人邮箱密码或授权码
    :param receiver_email: 收件人邮箱
    :param subject: 邮件主题
    :param body: 邮件正文
    :param file_path: 附件文件路径
    """
    # 创建邮件对象
    msg = MIMEMultipart()
    msg['From'] = sender_email
    msg['To'] = receiver_email
    msg['Subject'] = subject
    # 添加邮件正文
    msg.attach(MIMEText(body, 'plain', 'utf-8'))
    # 添加附件
    try:
        # 获取文件名
        filename = os.path.basename(file_path)
        # 以二进制模式打开文件
        with open(file_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= {filename}'
            )
            # 将附件添加到邮件
            msg.attach(part)
        print(f"成功添加附件: {filename}")
    except Exception as e:
        print(f"添加附件失败: {e}")
        return False
    # 发送邮件
    try:
        # 连接SMTP服务器(以QQ邮箱为例)
        server = smtplib.SMTP('smtp.qq.com', 587)
        server.starttls()  # 启用TLS加密
        # 登录邮箱
        server.login(sender_email, sender_password)
        # 发送邮件
        text = msg.as_string()
        server.sendmail(sender_email, receiver_email, text)
        print("邮件发送成功!")
        return True
    except Exception as e:
        print(f"邮件发送失败: {e}")
        return False
    finally:
        server.quit()
# 使用示例
if __name__ == "__main__":
    # 配置信息
    sender = "your_email@qq.com"  # 发件人邮箱
    password = "your_authorization_code"  # 邮箱授权码(不是登录密码)
    receiver = "receiver@example.com"  # 收件人邮箱
    # 发送带附件的邮件
    send_email_with_attachment(
        sender_email=sender,
        sender_password=password,
        receiver_email=receiver,
        subject="测试邮件附件",
        body="这是一封测试邮件,请查收附件。",
        file_path="test.pdf"
    )

多附件发送

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email import encoders
import os
def send_email_with_multiple_attachments(sender_email, sender_password, 
                                         receiver_email, subject, body, 
                                         file_paths):
    """
    发送多附件的邮件
    :param file_paths: 附件文件路径列表
    """
    msg = MIMEMultipart()
    msg['From'] = sender_email
    msg['To'] = receiver_email
    msg['Subject'] = subject
    # 添加HTML格式的邮件正文
    html_body = f"""
    <html>
      <body>
        <h2>{subject}</h2>
        <p>{body}</p>
        <p>附件列表:</p>
        <ul>
    """
    for file_path in file_paths:
        filename = os.path.basename(file_path)
        html_body += f"<li>{filename}</li>"
    html_body += """
        </ul>
      </body>
    </html>
    """
    msg.attach(MIMEText(html_body, 'html', 'utf-8'))
    # 遍历添加多个附件
    for file_path in file_paths:
        try:
            filename = os.path.basename(file_path)
            # 判断文件类型,选择合适的MIME类型
            if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')):
                # 图片文件
                with open(file_path, 'rb') as img:
                    part = MIMEImage(img.read(), name=filename)
            else:
                # 其他文件
                with open(file_path, 'rb') as attachment:
                    part = MIMEBase('application', 'octet-stream')
                    part.set_payload(attachment.read())
                    encoders.encode_base64(part)
            # 添加文件名到Content-Disposition
            part.add_header(
                'Content-Disposition',
                f'attachment; filename="{filename}"'
            )
            msg.attach(part)
            print(f"成功添加附件: {filename}")
        except Exception as e:
            print(f"添加附件 {file_path} 失败: {e}")
    # 发送邮件
    try:
        # 连接SMTP服务器(以163邮箱为例)
        server = smtplib.SMTP_SSL('smtp.163.com', 465)  # SSL加密连接
        server.login(sender_email, sender_password)
        text = msg.as_string()
        server.sendmail(sender_email, receiver_email, text)
        print("邮件发送成功!")
        return True
    except Exception as e:
        print(f"邮件发送失败: {e}")
        return False
    finally:
        server.quit()
# 使用示例
if __name__ == "__main__":
    # 多个附件
    files_to_attach = [
        "document.pdf",
        "image.png",
        "report.docx",
        "data.xlsx"
    ]
    send_email_with_multiple_attachments(
        sender_email="your_email@163.com",
        sender_password="your_authorization_code",
        receiver_email="receiver@example.com",
        subject="月度报告及附件",
        body="请查收本月的工作报告和相关资料。",
        file_paths=files_to_attach
    )

带附件的HTML邮件

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import os
def send_html_email_with_attachment(sender_email, sender_password, 
                                    receiver_email, subject, html_content,
                                    file_paths):
    """
    发送带附件的HTML格式邮件
    """
    msg = MIMEMultipart('mixed')
    msg['From'] = sender_email
    msg['To'] = receiver_email
    msg['Subject'] = subject
    # 创建HTML部分
    msg_alternative = MIMEMultipart('alternative')
    msg_alternative.attach(MIMEText(html_content, 'html', 'utf-8'))
    msg.attach(msg_alternative)
    # 添加附件
    for file_path in file_paths:
        try:
            filename = os.path.basename(file_path)
            with open(file_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="{filename}"'
            )
            msg.attach(part)
            print(f"已添加附件: {filename}")
        except Exception as e:
            print(f"添加附件失败: {e}")
    # 发送邮件
    try:
        # 使用GMail SMTP服务器
        with smtplib.SMTP('smtp.gmail.com', 587) as server:
            server.starttls()
            server.login(sender_email, sender_password)
            server.send_message(msg)
            print("邮件发送成功!")
            return True
    except Exception as e:
        print(f"邮件发送失败: {e}")
        return False
# 使用示例
if __name__ == "__main__":
    # HTML内容
    html_content = """
    <!DOCTYPE html>
    <html>
    <head>
        <style>
            body { font-family: Arial, sans-serif; }
            .attachment { color: blue; font-weight: bold; }
        </style>
    </head>
    <body>
        <h1>项目更新报告</h1>
        <p>您好,</p>
        <p>以下是本月项目的更新情况:</p>
        <ul>
            <li>完成了首要任务</li>
            <li>修复了3个关键bug</li>
            <li>新增了用户反馈功能</li>
        </ul>
        <p class="attachment">请在附件中查看详细报告。</p>
        <p>祝好!</p>
    </body>
    </html>
    """
    send_html_email_with_attachment(
        sender_email="your_email@gmail.com",
        sender_password="your_password",
        receiver_email="receiver@example.com",
        subject="项目更新报告 - 2024年1月",
        html_content=html_content,
        file_paths=["project_report.pdf", "screenshots.zip"]
    )

注意事项

邮箱授权码

大多数邮箱(QQ、163、Gmail等)需要使用授权码而不是登录密码:

# QQ邮箱授权码获取方法
# 设置 -> 账户 -> POP3/IMAP/SMTP服务 -> 生成授权码
# 163邮箱授权码获取方法
# 设置 -> POP3/SMTP/IMAP -> 新增授权码

不同邮箱的SMTP配置

# QQ邮箱
SMTP_SERVER = 'smtp.qq.com'
SMTP_PORT = 587  # TLS
# 或
SMTP_PORT = 465  # SSL
# 163邮箱
SMTP_SERVER = 'smtp.163.com'
SMTP_PORT = 25  # 普通
SMTP_PORT = 465  # SSL
# Gmail
SMTP_SERVER = 'smtp.gmail.com'
SMTP_PORT = 587  # TLS

文件大小限制

  • 大多数邮箱限制附件总大小不超过25MB
  • 超过限制需要分卷压缩或使用云存储链接

中文文件名处理

from email.header import Header
# 处理中文文件名
filename = "报告文件.pdf"
# 使用Header编码文件名
part.add_header(
    'Content-Disposition',
    f'attachment; filename="{Header(filename, "utf-8").encode()}"'
)

这个示例涵盖了Python发送邮件附件的主要场景,您可以根据实际需求调整使用。

抱歉,评论功能暂时关闭!