美文网首页
利用Python的smtplib和email发送邮件

利用Python的smtplib和email发送邮件

作者: MrYun | 来源:发表于2017-11-25 22:48 被阅读74次

    原理

    网上已经有了很多的教程讲解相关的发送邮件的原理,在这里还是推荐一下廖雪峰老师的Python教程,讲解通俗易懂。简要来说,SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。而python内置的email模块则是负责邮件的内容、发送方、接收方等内容;具体的操作可以看代码。

    而构造一个邮件对象就是一个Messag对象,如果构造一个MIMEText对象,就表示一个文本邮件对象,如果构造一个MIMEImage对象,就表示一个作为附件的图片,要把多个对象组合起来,就用MIMEMultipart对象,而MIMEBase可以表示任何对象。他们的嵌套关系如下:

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

    一些错误的总结

    [1]提示smtplib.SMTPAuthenticationError: (550, b'User has no permission')
    这是因为邮箱没有开启客户端授权,邮箱这边的SMTP服务运行不起来;而现在基本所有的邮件都是需要客户端授权的,这里需要注意一下。解决办法为:进入163邮箱-设置-客户端授权密码-开启(授权码是用于登录第三方邮件客户端的专用密码),非第三方登录密码不变。
    [2]提示smtplib.SMTPAuthenticationError: (535, b'Error: authentication failed')
     以163邮箱为例,在开启POP3/SMTP服务,并开启客户端授权密码时会设置授权码,将这个授权码代替smtplib.SMTP().login(user,password)方法中的password即可。就是说你代码中的password为你所设置的授权码。
    [3]提示554
    说明邮件内容缺少信息,在现在的邮箱里一般有些内容需要填写。

    代码

    # 发送文本
    # -*- coding: utf-8 -*-
    
    from email import encoders
    from email.header import Header
    from email.mime.text import MIMEText
    from email.utils import parseaddr, formataddr
    import smtplib
    
    def _format_addr(s):
        name, addr = parseaddr(s)
        return formataddr((Header(name, 'utf-8').encode(), addr))
    
    from_addr = input('From: ')
    password = input('Password: ')
    to_addr = input('To: ')
    smtp_server = input('SMTP server: ')
    
    # 发的内容
    msg = MIMEText('hello, send by Python...', 'plain', 'utf-8')
    # 发件人
    msg['From'] = _format_addr(u'Python爱好者 <%s>' % from_addr)
    # 收件人
    msg['To'] = _format_addr(u'管理员 <%s>' % to_addr)
    # 标题
    msg['Subject'] = Header(u'来自SMTP的问候……', 'utf-8').encode()
    
    server = smtplib.SMTP(smtp_server, 25)
    server.set_debuglevel(1)
    server.login(from_addr, password)
    server.sendmail(from_addr, [to_addr], msg.as_string())
    server.quit()
    
    # 发送附件
    # -*- coding: utf-8 -*-
    
    from email import encoders
    from email.header import Header
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from email.mime.base import MIMEBase
    from email.utils import parseaddr, formataddr
    import smtplib
    
    def _format_addr(s):
        name, addr = parseaddr(s)
        return formataddr((Header(name, 'utf-8').encode(), addr))
    
    from_addr = input('From: ')
    password = input('Password: ')
    to_addr = input('To: ')
    smtp_server = input('SMTP server: ')
    
    # 邮件对象:
    msg = MIMEMultipart()
    msg['From'] = _format_addr(u'Python爱好者 <%s>' % from_addr)
    msg['To'] = _format_addr(u'管理员 <%s>' % to_addr)
    msg['Subject'] = Header(u'来自SMTP的问候……', 'utf-8').encode()
    
    # 邮件正文是MIMEText:
    msg.attach(MIMEText('send with file...', 'plain', 'utf-8'))
    
    # 添加附件就是加上一个MIMEBase,从本地读取一个图片:
    with open('e:/141.m4a', 'rb') as f:
        # 设置附件的MIME和文件名,这里是音乐类型:
        mime = MIMEBase('image', 'm4a', filename='141.m4a')
        # 加上必要的头信息:
        mime.add_header('Content-Disposition', 'attachment', filename='141.m4a')
        mime.add_header('Content-ID', '<0>')
        mime.add_header('X-Attachment-Id', '0')
        # 把附件的内容读进来:
        mime.set_payload(f.read())
        # 用Base64编码:
        encoders.encode_base64(mime)
        # 添加到MIMEMultipart:
        msg.attach(mime)
    
    server = smtplib.SMTP(smtp_server, 25)
    server.set_debuglevel(1)
    server.login(from_addr, password)
    server.sendmail(from_addr, [to_addr], msg.as_string())
    server.quit()
    

    代码经笔者都测试过,应该是没问题的。遇到错误看看是不是客户端的授权问题,或者是python的版本的问题。

    相关文章

      网友评论

          本文标题:利用Python的smtplib和email发送邮件

          本文链接:https://www.haomeiwen.com/subject/yyjhbxtx.html