• python SMTP 发送邮件


    SMTP 发送邮件过程

    1.连接到服务器

    2.登录(根据需要)

    3.发出服务请求

    4.退出

    保证邮件能发送成功, 一般需要配置好邮箱设置. 网页登录邮件, 检查 "POP3/SMTP服务" 状态是否开启, 同时可找到SMTP服务器(如 smtp.sina.cn).

    登录时使用自己的邮箱账号和密码即可.

    Python 有一个 smtplib 模块用于发送邮件, 发送邮件只需实例化 smtplib.SMTP 类.

    SMTP类方法

    sendmail(from, to, msg[, mopts, ropts])      将 msg  从 from(发件人) 发送至 to(收件人列表或无组表示). 还可以选择性地设置 ESMTP 邮件(mopts) 和收件人 (ropts) 选项.

    ehlo() 或 helo()  使用 EHLO 或 HELO 初始化 SMTP 或 ESMTP 服务器对话. 这是可选的, 因为 sendmail() 会在需要时自动调用相关内容.

    starttls(keyfile = None, certfile = None)   让服务器启用 TLS 模式, 如果给定了 keyfile 或 cerfile, 则它们用来创建安全套接字.

    set_debuglevel(level)  为服务器通信设置调试级别.

    quit()  关闭连接并退出

    login(user, passwd)   使用用户名和密码登录 SMTP 服务器

    邮件消息对象

    邮件对象使用 Messag 类, 如果构造一个 MIMEText 对象, 就表示一个文本邮件对象, 如果构造一个 MIMEImage 对象, 就表示一个作为附件的图片, 要把多个对象组合起来, 就用 MIMEMultipart 对象, 而 MIMEBase 可以表示任何对象.

    它们之间的关系如下:

    Message
    +- MIMEBase
       +- MIMEMultipart
       +- MIMENonMultipart
          +- MIMEMessage
          +- MIMEText
          +- MIMEImage

    将一个图片嵌入到正文

    邮件服务商大都会自动屏蔽带有外链的图片, 因为不知道这些链接是否指向恶意网站. 因此要把图片嵌入到邮件正文中, 我们需先按照发送附件的方式, 先把邮件作为附件添加进去, 然后在 HTML 中通过引用 src="cid:0"这种方式嵌入, 注意其中的id为插入附件时指定的id.

    htmlText = '<html><body><h1>{}</h1><p><img src="cid:{}"></p></body></html>'.format(text, imgId)
            mimeText = MIMEText(htmlText, 'html', "utf-8")
            self.msg.attach(mimeText)

    完整源码示例 

    from email import encoders
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    from email.header import Header
    from email.mime.base import MIMEBase
    from smtplib import SMTP
    import os.path
    
    
    class SmtpEmail():
        def __init__(self, serverAddr, user, passwd):
            self.serverAddr = serverAddr
            self.user = user
            self.passwd = passwd
            self.id = 0
            self.msg = MIMEMultipart()
            self.msg['Subject'] = Header("无主题", "utf-8")
            self.msg['From'] = Header(user)
            self.toAddrs = []
    
        def addToAddr(self, toAddr):
            self.toAddrs.append(toAddr)
    
        def setSubject(self, subject):
            self.msg['Subject'] = Header(subject, "utf-8")
    
        def addPlainText(self, text):
            # 这里本可以像下面这样创建一个 plain 的消息, 但是部分客户端软件不能同时显示 plain 和 html, 因此将 plain 转换为 html.
            # mimeText = MIMEText(text, "plain", "utf-8")
            htmlText = '<html><body><h1>{}</h1></body></html>'.format(text)
            mimeText = MIMEText(htmlText, 'html', "utf-8")
            self.msg.attach(mimeText)
            
        def addTextImage(self, text, imgId):
            htmlText = '<html><body><h1>{}</h1><p><img src="cid:{}"></p></body></html>'.format(text, imgId)
            mimeText = MIMEText(htmlText, 'html', "utf-8")
            self.msg.attach(mimeText)
    
        def addAttachment(self, filePath, mainType, subType):
            with open(filePath, 'rb') as f:
                id = self.id
                self.id += 1
                fileBaseName = os.path.basename(filePath);
                mime = MIMEBase(mainType, subType, filename = fileBaseName)
                mime.add_header("Content-Disposition", "attachment", filename = fileBaseName)
                mime.add_header("Content-ID", "<{}>".format(id))
                mime.add_header("X-Attachment-Id", "{}".format(id))
                mime.set_payload(f.read())
                encoders.encode_base64(mime)
                self.msg.attach(mime)
                return id
            return None
    
        def sendTo(self):
            assert self.toAddrs, "收件人不能为空"
            self.smtp = SMTP(self.serverAddr, 25)
            self.smtp.set_debuglevel(1)
            self.smtp.login(self.user, self.passwd)
            self.smtp.sendmail(self.user, self.toAddrs, self.msg.as_string())
            self.smtp.quit()
            self.smtp.close()
    
    def main():
        import argparse
        parser = argparse.ArgumentParser()
        parser.add_argument("-user", "--user")
        parser.add_argument("-passwd", "--passwd")
        args = parser.parse_args()
        user = args.user
        passwd = args.passwd
        assert user and passwd, "invalid user or passwd."
    
        smtpEmail = SmtpEmail("smtp.sina.cn", user, passwd)
        smtpEmail.addToAddr(user) # 发送一个邮件给自己
        smtpEmail.setSubject("测试邮件")
        id = smtpEmail.addAttachment("file/come_on.png", "image", "png")
        if id is not None:
            smtpEmail.addTextImage("Come on", id)
        smtpEmail.addPlainText("This is an automatically sent email, please do not reply! 
    Thank you.
    ")
        smtpEmail.addPlainText("This is an automatically sent email, please do not reply! 
    Thank you.
    ")
        smtpEmail.addPlainText("This is an automatically sent email, please do not reply! 
    Thank you.
    ")
        smtpEmail.addAttachment("file/test.xlsx", "file", "xlsx")
        smtpEmail.sendTo()
    
    
    
    if __name__ == "__main__":
        main()
  • 相关阅读:
    OpenCV 写入视频流
    Flyweight 模式
    Builder 模式
    MySQL插入数据
    MySQL新建表
    2's Power
    DeepID人脸识别算法之三代(转)
    FaceNet--Google的人脸识别(转)
    DeepFace--Facebook的人脸识别(转)
    leetcode6 Reverse Words in a String 单词取反
  • 原文地址:https://www.cnblogs.com/diysoul/p/10631235.html
Copyright © 2020-2023  润新知