• 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()

    发送结果如下

  • 相关阅读:
    vs 文件头自动添加注释
    .NET开发人员必知的八个网站
    鼠标移动到曲线图上显示值
    显示器分辨率不同,部分winform控件在其他机器上显示不全
    dotnetcharting 的简单使用
    C#Winform中ToolTip的简单用法,
    SQL Server 2008 报错:已成功与服务器建立连接,但是在登录前的握手期间发生错误
    开源组件整理
    java实现控件的移动及使用鼠标改变控件大小
    基础知识点七
  • 原文地址:https://www.cnblogs.com/testlearn/p/14548396.html
Copyright © 2020-2023  润新知