zoukankan      html  css  js  c++  java
  • 利用Python 发送邮件

    概要

      我们都知道SMTP(简单邮件传输协议),是一组用于从原地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP规定电子邮件应该如何格式化、如何加密,以及如何在邮件服务器之间传递。SMTP服务器就是通过遵循SMTP协议的发送邮件服务器。

      如果你使用过邮件客户端,比如Foxmail,outlook等,那么你应该了解SMTP服务器和端口号,除了服务器和端口,我们还需要进行其他配置,默认情况下邮件服务提供商是不允许我们使用程序进行邮件发送的,如果想要使用程序发送电子邮件,就需要我们手动开启SMTP服务,并获取一个专用的授权码(用于登陆)。   -- 需要自行去了解所用邮箱的授权码获取方式

    使用smtplib和email模块发送邮件

      得到邮箱的授权码就可以使用Python代码发送电子邮件了。Python标准库有多个与邮件相关的模块,其中smtplib负责发送邮件,email模块用来构造邮件和解析邮件内容。

    smtplib模块

      stmplib发送邮件大概分为以下几个步骤:

    1. 连接到SMTP服务器
    2. 发送SMTP的“Hello”消息
    3. 登陆到SMTP服务器
    4. 发送电子邮件
    5. 关闭SMTP服务器的连接

      对于简单的邮件,smtplib的使用是非常简单的,下面是实例

    # 导入smtplib模块
    import smtplib
    
    # 创建SMTP对象,括号内为SMTP服务器地址及端口号
    smtp = smtplib.SMTP('smtp.qq.com',25)
    
    # 向SMTP服务器打一个招呼,查看连接状态
    smtp.ehlo()
    (250, b'smtp.qq.com
    PIPELINING
    SIZE 73400320
    STARTTLS
    AUTH LOGIN PLAIN
    AUTH=LOGIN
    MAILCOMPRESS
    8BITMIME')
    
    # 连接使用TLS加密(然后就可以传递敏感信息了),否则无法使用login方法登陆会提示SMTPServerDisconnected 异常
    smtp.starttls()
    (220, b'Ready to start TLS')
    
    # 登陆邮箱,传递的是用户名密码
    smtp.login('287990400@qq.com','oiifptyw......')    # 授权码
    (235, b'Authentication successful')
    
    # 发送邮件
    smtp.sendmail('287990400@qq.com','932911203@qq.com','Subject:this is title
     this is content')
    {}
    
    # 邮件发送完毕后关闭链接
    smtp.quit()
    (221, b'Bye')
    

      PS:sendmail的参数为发件人,收件人,邮件内容

      注意:可以在创建加密链接之前使用smtp.set_debuglevel(1),来显示与SMTP服务器交互的相关信息

      查看发送的邮件会发送,有两个问题,一是收件人栏为空,二是邮件内容缺失,这是因为邮件主题、如何显示发件人、收件人等信息并不是通过SMTP协议发给MTA,而是包含在发给MTA的文本中的,所以,我们必须把FromToSubject添加到email模块中的MIMEText中,才是一封完整的邮件。(MTA可以理解为邮件代理服务器)。

    smtplib模块结合email模块

      使用email模块构建一个邮件对象(Message),email模块中支持很多邮件对象

    • MIMEText:表示一个纯文本的邮件     * 常用
    • MIMEImage:表示一个作为附件的图片
    • MIMEMultipart:用于把多个对象组合起来

      其中还有诸如其他的类:MIMEBase、MIMEAudio等。

    MIMEText对象的主要参数是:MIMEText(_text, _subtype='plain', _charset=None),其中:

    • _text:表示邮件内容
    • _subtype:表示邮件内容的类型,默认为plain(纯文本),还可以设置为html,表示正文是html文件(会渲染HTML标签)
    • _charset:表示邮件编码,默认情况下使用ascii编码

      下面是一个发送纯文本邮件的例子:

    #!/usr/bin/env python3
    
    import smtplib
    from email.mime.text import MIMEText
    
    SMTP_SERVER = 'smtp.qq.com'
    SMTP_PORT = 25
    
    def send_mail(user,passwd,to,subject,text):
        msg = MIMEText(text)
        msg['From'] = user            # 构建msg对象的发件人
        msg['to'] = to                # 构建msg对象的收件人
        msg['Subject'] = subject      # 构建msg对象的邮件正文
    
        smtp_server = smtplib.SMTP(SMTP_SERVER,SMTP_PORT)
        print('Connecting To mail Server')
        try:
            smtp_server.ehlo()
            print('Starting Encrypted Session.')
            smtp_server.starttls()
            smtp_server.ehlo()
            print('Loggin Into Mail Server.')
            smtp_server.login(user,passwd)
            print('Send mail.')
            smtp_server.sendmail(user,to,msg.as_string())   # 利用msg的as_string()方法转换成字符串
        except Exception as err:
            print('Sending Mail Failed:{0}'.format(err))
    
        finally:
            smtp_server.quit()
    
    
    def main():
        send_mail('287990400@qq.com','vgdw...ucafc','932911203@qq.com','Important','Text Message from dahlhin')
    
    if __name__ == '__main__':
        main()
                                                                                                                  
    

    PS:利用msg对象,我们可以构建邮件的header,通过添加header信息,给邮件增加subject等参数,达到补全邮件信息的目的。msg的header添加方式和使用字典的方式相同。

    带附件的邮件

      前面说明了发送纯文本邮件的方法,在使用邮件发送带附件(图片)的邮件时,需要使用MIMEMultipart对象,并把MIMEImage对象添加。

    import smtplib
    import os
    from email.mime.image import MIMEImage
    from email.mime.multipart import MIMEMultipart
    from email.mime.application import MIMEApplication
    
    SMTP_SERVER = 'smtp.qq.com'
    SMTP_PORT = 25
    
    
    def send_mail(user, passwd, to, subject, text):
        msg = MIMEMultipart(text)
        msg['From'] = user  # 构建msg对象的发件人
        msg['to'] = to  # 构建msg对象的收件人
        msg['Subject'] = subject  # 构建msg对象的邮件正文
        msg.preamble = subject
    
        smtp_server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
        print('Connecting To mail Server')
        try:
            smtp_server.ehlo()
            print('Starting Encrypted Session.')
            smtp_server.starttls()
            smtp_server.ehlo()
            print('Loggin Into Mail Server.')
            smtp_server.login(user, passwd)
    
    
            # 添加图片附件
            url = r'C:UsersAre you SuperManPicturesSaved Pictures'
            for img in os.listdir(url):
    
                jpgpart = MIMEImage(open(os.path.join(url,img),'rb').read(),'png')
                jpgpart.add_header('Content-Disposition', 'attachment', filename=img)    # 用于告知浏览器下载附件文件时的名称
                msg.attach(jpgpart)
    
    
            print('Send mail.')
            smtp_server.sendmail(user, to, msg.as_string())  # 利用msg的as_string()方法进行转换
        except Exception as err:
            print('Sending Mail Failed:{0}'.format(err))
    
        finally:
            smtp_server.quit()
    
    
    def main():
        send_mail('287990400@qq.com', 'jwxpwixnpruwcabj', '932911203@qq.com', 'Important2', 'Text Message from dahlhin')
    
    
    if __name__ == '__main__':
        main()
    

    使用yagmail发送邮件 

      Python的标准库smtplib和email,相对来说还是比较复杂的,因此许多开源项目提供了更加易用的接口来发送邮件。比如yagmail就是一个使用比较广泛的开源项目,它依旧使用smtplib和email模块,但是相对于直接使用smtplib和email模块,它提供了更加Pythonic的接口,并具有更好的易用性。

      由于yagmail属于第三方库,在使用前需要先行安装

    pip3 install yagmail
    

      下面使用yagmail发送一封简单的邮件

    server = yagmail.SMTP(user='287990400@qq.com',password='vgdwgrziieducafc',host='smtp.qq.com',port=25,smtp_starttls=True,smtp_ssl=False)
    content = ['this is my first mail','used for yagmail']
    server.send('932911203@qq.com','IMPORTANT',content)          # 对方邮箱,主题,邮件内容
    

      如果要携带附件那么只需要在send后面添加即可

    server = yagmail.SMTP(user='287990400@qq.com',password='vgdwgrziieducafc',host='smtp.qq.com',port=25,smtp_starttls=True,smtp_ssl=False)
    content = ['this is my first mail','used for yagmail']
    server.send('932911203@qq.com','Images',content,['/Users/DahlHin/Desktop/image.jpg'])
    

      再也没有这么好用的第三方邮件库了

  • 相关阅读:
    [LeetCode] Word Break 解题思路
    [LeetCode] Longest Valid Parentheses 解题思路
    [LeetCode] Largest Rectangle in Histogram 解题思路
    新博客
    正在学习的Angularjs包裹的插件
    Markdown
    Markdown 基础
    Angular docs
    npm-link
    webpack-hot-middleware 用于 livereload
  • 原文地址:https://www.cnblogs.com/dachenzi/p/8655022.html
Copyright © 2011-2022 走看看