Python_使用smtplib+email完成邮件发送

本文以第三方QQ邮箱服务器演示如何使用python的smtplib+email完成邮箱发送功能

一、设置开启SMTP服务并获取授权码

开启QQ邮箱SMTP服务

 开启的最后一步是发送短信验证,获取 authorization。 QQ官方获取授权码的帮助文档

使用SMTP服务有POP和IMAP(Internet Message Access Protocol)两种协议,我们选择使用IMAP,具体差异查看QQ邮箱帮助文档

使用IMAP服务的SSL加密方式的通用配置如下:
接收邮件服务器:imap.qq.com,使用SSL,端口号993
发送邮件服务器:smtp.qq.com,使用SSL,端口号465或587
账户名:您的QQ邮箱账户名(如果您是VIP帐号或Foxmail帐号,账户名需要填写完整的邮件地址)
密码:您的QQ邮箱authorization
电子邮件地址:您的QQ邮箱的完整邮件地址

二、发送文本类型的邮箱

import smtplib
from email.mime.text import MIMEText


# 1.连接邮件服务器
smtpHost = "smtp.qq.com"    # 邮件服务器地址
port = 465      # 邮件服务器端口
server = smtplib.SMTP_SSL(smtpHost, port)

# 2.登录服务
sender = '418***167@qq.com'    # 发件人邮箱账号
authorization = 'spi********idj'      # QQ邮箱授权码
server.login(sender, authorization)  # 括号中对应的是发件人邮箱账号、邮箱密码

# 3.构造邮件内容
# 3.1 创建邮箱容器
mailboxContainer = MIMEText('Hello Python!', "plain", "utf-8")   # 创建文本类型容器

# 3.2 定义容器内容
mailboxContainer['Subject'] = "python发送的邮件"     # 邮箱主题
mailboxContainer['From'] = sender           # 邮箱发送人
receiver_to = ['y****@****.com']
mailboxContainer["To"] = ",".join(receiver_to)  # 邮箱接收人
receiver_cc = []
mailboxContainer['Cc'] = ",".join(receiver_cc)   # 邮箱抄送人

# 4.发送邮件
receiver = receiver_to + receiver_cc    # 接收邮箱的人(包含接收和抄送)
server.sendmail(sender, receiver, mailboxContainer.as_string())

# 5.关闭连接
server.quit()

收件结果如下:

三、发送HTML类型的邮件

import smtplib
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText


# 1.连接邮件服务器
smtpHost = "smtp.qq.com"    # 邮件服务器地址
port = 465      # 邮件服务器端口
server = smtplib.SMTP_SSL(smtpHost, port)

# 2.登录服务
sender = '418XXXX167@qq.com'    # 发件人邮箱账号
authorization = 'spiXXXXXXXidj'      # QQ邮箱授权码
server.login(sender, authorization)  # 括号中对应的是发件人邮箱账号、邮箱密码

# 3.构造邮件内容
# 3.1 创建邮箱容器
# mailboxContainer = MIMEText('邮件正文内容', "plain", "utf-8")   # 创建文本类型容器
mailboxContainer = MIMEMultipart()      # 创建混合类型容器

# 3.2 定义容器内容
mailboxContainer['Subject'] = "测试python发送邮件"     # 邮箱主题
mailboxContainer['From'] = sender           # 邮箱发送人
receiver_to = ['yXXo@XXXXX.com']
mailboxContainer["To"] = ",".join(receiver_to)  # 邮箱接收人
receiver_cc = []
mailboxContainer['Cc'] = ",".join(receiver_cc)   # 邮箱抄送人
# 混合类型,添加html内容
mail_msg = """
<p>Python 邮件发送测试...</p>
<p>图片演示:</p>
<p><img src="cid:image1"></p>
"""
mailboxContainer.attach(MIMEText(mail_msg, 'html', 'utf-8'))

# 读取图片信息
with open(r".h5_img.jpg", "rb") as f:
    msg = f.read()
msgImage = MIMEImage(msg)

# 定义图片 ID,在 HTML 文本中引用
msgImage.add_header('Content-ID', '<image1>')
mailboxContainer.attach(msgImage)

# 4.发送邮件
receiver = receiver_to + receiver_cc    # 接收邮箱的人(包含接收和抄送)
server.sendmail(sender, receiver, mailboxContainer.as_string())

# 5.关闭连接
server.quit()

接收结果如下:

四、发送带附件的邮件

import smtplib
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText


# 1.连接邮件服务器
smtpHost = "smtp.qq.com"    # 邮件服务器地址
port = 465      # 邮件服务器端口
server = smtplib.SMTP_SSL(smtpHost, port)

# 2.登录服务
sender = '41XXXX7@qq.com'    # 发件人邮箱账号
authorization = 'spXXXXXXdj'      # QQ邮箱授权码
server.login(sender, authorization)  # 括号中对应的是发件人邮箱账号、邮箱密码

# 3.构造邮件内容
# 3.1 创建邮箱容器
# mailboxContainer = MIMEText('邮件正文内容', "plain", "utf-8")   # 创建文本类型容器
mailboxContainer = MIMEMultipart()      # 创建混合类型容器

# 3.2 定义容器内容
mailboxContainer['Subject'] = "带附件的邮箱"     # 邮箱主题
mailboxContainer['From'] = sender           # 邮箱发送人
receiver_to = ['yXXX@XXXXX.com']
mailboxContainer["To"] = ",".join(receiver_to)  # 邮箱接收人
receiver_cc = []
mailboxContainer['Cc'] = ",".join(receiver_cc)   # 邮箱抄送人
# # 混合类型,添加文本内容
mailboxContainer.attach(MIMEText('测试带附件的邮箱', "plain", "utf-8"))

# 构造文本附件
with open(r".	ext.txt", "rb") as f:
    msg = f.read()
att1 = MIMEText(msg, 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
att1["Content-Disposition"] = 'attachment; filename="text.txt"'   # 这里的filename可以任意写,写什么名字,邮件附件中显示什么名字
mailboxContainer.attach(att1)

# 构造图片附件
with open(r".h5_img.jpg", "rb") as f:
    msg = f.read()
att2 = MIMEText(msg, 'base64', 'utf-8')
att2["Content-Type"] = 'application/octet-stream'
# att2["Content-Disposition"] = 'attachment; filename="h5_img"'   # 这里的filename可以任意写,写什么名字,邮件中显示什么名字
att2.add_header('content-disposition', 'attachment', filename='h5.jpg')      # 与上面注释代码功能一样
mailboxContainer.attach(att2)

# 4.发送邮件
receiver = receiver_to + receiver_cc    # 接收邮箱的人(包含接收和抄送)
server.sendmail(sender, receiver, mailboxContainer.as_string())

# 5.关闭连接
server.quit()

接收结果如下:

五、初步封装

import os
import smtplib
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from utils.file import file


class SMTP:
    def __init__(self, smtp_host="smtp.qq.com", port=465):
        # 连接邮件服务器
        self.__server = smtplib.SMTP_SSL(smtp_host, port)
        self.__sender = None  # 发件人邮箱账号
        self.__mailboxContainer = MIMEMultipart()  # 创建邮箱容器
        self.__receiver = []

    def quit(self):
        self.__server.quit()

    def login(self, account, authorization):
        """登录邮箱服务器"""
        self.__sender = account
        self.__server.login(account, authorization)  # 括号中对应的是发件人邮箱账号、邮箱密码

    def add_subject(self, subject):
        """添加邮件主题"""
        self.__mailboxContainer['Subject'] = subject  # 邮箱主题

    def add_receiver(self, receiver_to: list, receiver_cc: list = None):
        """
        添加邮件接收人
        receiver_to:收件人
        receiver_cc:抄送人
        """
        self.__mailboxContainer["From"] = self.__sender
        self.__mailboxContainer["To"] = ",".join(receiver_to)  # 邮箱接收人
        self.__mailboxContainer['Cc'] = ",".join(receiver_cc)   # 邮箱抄送人
        self.__receiver = receiver_to + receiver_cc

    def add_content(self, content, mail_type="plain", append_imgs: list = None):
        """
        添加邮箱内容
        content:邮箱内容
        mail_type:内容的类型
        append_imgs:当为html类型时追加图片内容
        """
        if mail_type != "html" and append_imgs is not None:
            raise ValueError(f"main_type的值不为html,但append_img不是空")

        if mail_type == "html" and append_imgs is not None:
            for append_img in append_imgs:
                img_tag = f"<p><img src='cid:image{append_imgs.index(append_img)}'></p>"
                content += img_tag
                # 读取图片信息
                with open(append_img, "rb") as f:
                    msg = f.read()
                msgImage = MIMEImage(msg)

                # 定义图片 ID,在 HTML 文本中引用
                msgImage.add_header('Content-ID', f'<image{append_imgs.index(append_img)}>')
                self.__mailboxContainer.attach(msgImage)
        self.__mailboxContainer.attach(MIMEText(content, mail_type, "utf-8"))

    def add_attach(self, file_path):
        """添加单个附件"""
        if not os.path.exists(file_path):
            raise ValueError(f"文件【{file_path}】不存在")

        if not os.path.isfile(file_path):
            raise ValueError(f"【{file_path}】不是文件")

        # 构造文本附件
        with open(file_path, "rb") as f:
            msg = f.read()
        att = MIMEText(msg, 'base64', 'utf-8')
        att["Content-Type"] = 'application/octet-stream'
        filename = file.get_path_last_name(file_path)
        att["Content-Disposition"] = f'attachment; filename="{filename}"'  # 这里的filename可以任意写,写什么名字,邮件附件中显示什么名字
        self.__mailboxContainer.attach(att)

    def add_attachs(self, file_paths: list):
        """添加多个附件"""
        for file_path in file_paths:
            self.add_attach(file_path)

    def send(self):
        """发送邮件"""
        self.__server.sendmail(self.__sender, self.__receiver, self.__mailboxContainer.as_string())


if __name__ == '__main__':

    mailbox = SMTP()

    # 登录邮箱服务器
    account = '418XXXX167@qq.com'
    authorization = 'spiXXXXXidj'  # QQ邮箱授权码
    mailbox.login(account, authorization)

    # 添加邮箱主题
    mailbox.add_subject("使用SMTP封装类发送的邮件")

    # 添加邮箱接收人
    receiver_to = ['yXXXo@XXX.com']     # 收件人
    receiver_cc = ['41XXX7@qq.com']     # 抄送人
    mailbox.add_receiver(receiver_to, receiver_cc)

    # 添加邮箱内容
    mail_content = """
    <p>Python 邮件发送测试...</p>
    <p>追加图片如下</p>
    """
    append_imgs = [r".h5_img.jpg", r".doudou.png"]
    mailbox.add_content(mail_content, mail_type="html", append_imgs=append_imgs)

    # 添加附件
    mailbox.add_attach("text.txt")
    mailbox.add_attachs([r".h5_img.jpg", r".doudou.png"])

    # 发送邮箱
    mailbox.send()

发送结果如下

原文地址:https://www.cnblogs.com/testlearn/p/14548396.html