zoukankan      html  css  js  c++  java
  • python:利用smtplib发送邮件详解

    本文转自:https://www.cnblogs.com/insane-Mr-Li/p/9121619.html

    自动化测试中,测试报告一般都需要发送给相关的人员,比较有效的一个方法是每次执行完测试用例后,将测试报告(HTML、截图、附件)通过邮件方式发送。

    首先我们要做:

    进入163邮箱,点击设置中的pop3/smtp/imap

    开启smtp服务,如果没有开启,点击设置,手机号验证后勾选开启即可,开启后图如下:

    主要用到的就是smtp服务器:smtp.163.com

    然后设置客户端授权密码:

    记住密码,如果不记得密码在这重新授权。手机号验证即可重新授权。这个密码一会写代码的时候要用

    设置成功后,开始写代码

    一、python对SMTP的支持

    SMTP(Simple Mail Transfer Protocol)是简单传输协议,它是一组用于用于由源地址到目的地址的邮件传输规则。

    python中对SMTP进行了简单的封装,可以发送纯文本邮件、HTML邮件以及带附件的邮件。

    1、python对SMTP的支持

    ①email模块:负责构建邮件

    ②smtplib模块:负责发送邮件

    可以通过help()方法查看SMTP提供的方法:

    复制代码
    复制代码
     1 >>> from smtplib import SMTP
     2 >>> help(SMTP)
     3 Help on class SMTP in module smtplib:
     4 
     5 class SMTP(builtins.object)
     6  |  This class manages a connection to an SMTP or ESMTP server.
     7  |  SMTP Objects:
     8  |      SMTP objects have the following attributes:
     9  |          helo_resp
    10  |              This is the message given by the server in response to the
    11  |              most recent HELO command.
    12  |  
    13  |          ehlo_resp
    14  |              This is the message given by the server in response to the
    15  |              most recent EHLO command. This is usually multiline.
    16  |  
    17  |          does_esmtp
    18  |              This is a True value _after you do an EHLO command_, if the
    19  |              server supports ESMTP.
    20 | ......
    复制代码
    复制代码

     导入SMTP,查看对象注释。。。。。。

    2、sendmail()方法的使用说明

    ①connect(host,port)方法参数说明

      host:指定连接的邮箱服务器

      port:指定连接的服务器端口

    ②login(user,password)方法参数说明

      user:登录邮箱用户名

      password:登录邮箱密码

    ③sendmail(from-addr,to_addrs,msg...)方法参数说明

      from_addr:邮件发送者地址

      to_addrs:字符串列表,邮件发送地址

      msg:发送消息

    ④quit():结束当前会话

    ♦在smtplib库中,主要主要用smtplib.SMTP()类,用于连接SMTP服务器,发送邮件。

    这个类有几个常用的方法:

    方法

    描述

    SMTP.set_debuglevel(level) 设置输出debug调试信息,默认不输出
    SMTP.docmd(cmd[, argstring]) 发送一个命令到SMTP服务器
    SMTP.connect([host[, port]]) 连接到指定的SMTP服务器
    SMTP.helo([hostname]) 使用helo指令向SMTP服务器确认你的身份
    SMTP.ehlo(hostname) 使用ehlo指令像ESMTP(SMTP扩展)确认你的身份
    SMTP.ehlo_or_helo_if_needed() 如果在以前的会话连接中没有提供ehlo或者helo指令,这个方法会调用ehlo()或helo()
    SMTP.has_extn(name) 判断指定名称是否在SMTP服务器上
    SMTP.verify(address) 判断邮件地址是否在SMTP服务器上
    SMTP.starttls([keyfile[, certfile]]) 使SMTP连接运行在TLS模式,所有的SMTP指令都会被加密
    SMTP.login(user, password) 登录SMTP服务器
    SMTP.sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[])

    发送邮件

    from_addr:邮件发件人

    to_addrs:邮件收件人

    msg:发送消息

    SMTP.quit() 关闭SMTP会话
    SMTP.close() 关闭SMTP服务器连接

    二、发送不同格式的邮件

    1、纯文本格式的邮件

    复制代码
    # coding=utf-8
    import smtplib
    from email.mime.text import MIMEText
    # 发送纯文本格式的邮件
    msg = MIMEText('hello,send by python_test...','plain','utf-8')
    #发送邮箱地址
    sender = 'sender@163.com'
    #邮箱授权码,非登陆密码
    password = 'xxxxx'
    #收件箱地址
    receiver = 'receiver@qq.com'
    mailto_list = ['liqiang22230@163.com','10116340931@qq.com']#收件人
    #smtp服务器
    smtp_server = 'smtp.163.com'
    #发送邮箱地址
    msg['From'] = sender
    #收件箱地址
    msg['To'] =';'.join(mailto_list)#发送多人邮件写法
    #主题 
    msg['Subject'] = 'from IMYalost'

    server = smtplib.SMTP(smtp_server,25)# SMTP协议默认端口是25
    server.login(sender,password)#ogin()方法用来登录SMTP服务器
    server.set_debuglevel(1)#打印出和SMTP服务器交互的所有信息。
    server.sendmail(sender,mailto_list,msg.as_string())#msg.as_string()把MIMEText对象变成str server.quit()
    # 第一个参数为发送者,第二个参数为接收者,可以添加多个例如:['SunshineWuya@163.com','xxx@qq.com',]# 第三个参数为发送的内容
    server.quit()
    复制代码

    我们用set_debuglevel(1)就可以打印出和SMTP服务器交互的所有信息。SMTP协议就是简单的文本命令和响应。login()方法用来登录SMTP服务器,sendmail()方法就是发邮件,由于可以一次发给多个人,所以传入一个list,邮件正文是一个str,as_string()把MIMEText对象变成str。

    附一段例子:

    复制代码
    #coding:utf-8   #强制使用utf-8编码格式
    import smtplib  #加载smtplib模块
    from email.mime.text import MIMEText
    from email.utils import formataddr
    my_sender='发件人邮箱账号' #发件人邮箱账号,为了后面易于维护,所以写成了变量
    my_user='收件人邮箱账号' #收件人邮箱账号,为了后面易于维护,所以写成了变量
    def mail():
        ret=True
        try:
            msg=MIMEText('填写邮件内容','plain','utf-8')
            msg['From']=formataddr(["发件人邮箱昵称",my_sender])   #括号里的对应发件人邮箱昵称、发件人邮箱账号
            msg['To']=formataddr(["收件人邮箱昵称",my_user])   #括号里的对应收件人邮箱昵称、收件人邮箱账号
            msg['Subject']="主题" #邮件的主题,也可以说是标题
    
            server=smtplib.SMTP("smtp.xxx.com",25)  #发件人邮箱中的SMTP服务器,端口是25
            server.login(my_sender,"发件人邮箱密码")    #括号中对应的是发件人邮箱账号、邮箱密码
            server.sendmail(my_sender,[my_user,],msg.as_string())   #括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
            server.quit()   #这句是关闭连接的意思
        except Exception:   #如果try中的语句没有执行,则会执行下面的ret=False
            ret=False
        return ret
    
    ret=mail()
    if ret:
        print("ok") #如果发送成功则会返回ok,稍等20秒左右就可以收到邮件
    else:
        print("filed")  #如果发送失败则会返回filed
    复制代码

    如果发送成功则会返回ok,否则为执行不成功,如下图:

    2、HTML格式的邮件

    如果想发送HTML类型的邮件,只需要下面的一段代码即可:

    msg = MIMEText('<html><body><h1>Hello</h1>' +
      '<p>send by <a href="http://www.python.org">Python</a>...</p>' +
      '</body></html>', 'html', 'utf-8')

    再发一封邮件显示如下:

    ♦ 发送送不同格式的附件:

    基本思路就是,使用MIMEMultipart来标示这个邮件是多个部分组成的,然后attach各个部分。如果是附件,则add_header加入附件的声明。
    在python中,MIME的这些对象的继承关系如下。
    MIMEBase
        |-- MIMENonMultipart
            |-- MIMEApplication
            |-- MIMEAudio
            |-- MIMEImage
            |-- MIMEMessage
            |-- MIMEText
        |-- MIMEMultipart
    一般来说,不会用到MIMEBase,而是直接使用它的继承类。MIMEMultipart有attach方法,而MIMENonMultipart没有,只能被attach。
    MIME有很多种类型,这个略麻烦,如果附件是图片格式,我要用MIMEImage,如果是音频,要用MIMEAudio,如果是word、excel,我都不知道该用哪种MIME类型了,得上google去查。
    最懒的方法就是,不管什么类型的附件,都用MIMEApplication,MIMEApplication默认子类型是application/octet-stream。
    application/octet-stream表明“这是个二进制的文件,希望你们那边知道怎么处理”,然后客户端,比如qq邮箱,收到这个声明后,会根据文件扩展名来猜测。

    下面上代码。
    假设当前目录下有foo.xlsx/foo.jpg/foo.pdf/foo.mp3这4个文件。

    复制代码
    import smtplib 
    from email.mime.multipart import MIMEMultipart 
    from email.mime.text import MIMEText 
    from email.mime.application import MIMEApplication 
    _user = "sigeken@qq.com"
    _pwd = "***"
    _to  = "402363522@qq.com"
       
    #如名字所示Multipart就是分多个部分 # 构造一个MIMEMultipart对象代表邮件本身 
    msg = MIMEMultipart() 
    msg["Subject"] = "don't panic"
    msg["From"]  = _user 
    msg["To"]   = _to 
       
    #---这是文字部分--- 
    part = MIMEText("乔装打扮,不择手段") 
    msg.attach(part) 
       
    #---这是附件部分--- 
    #xlsx类型附件 
    part = MIMEApplication(open('foo.xlsx','rb').read()) 
    part.add_header('Content-Disposition', 'attachment', filename="foo.xlsx") 
    msg.attach(part) 
       
    #jpg类型附件 
    part = MIMEApplication(open('foo.jpg','rb').read()) 
    part.add_header('Content-Disposition', 'attachment', filename="foo.jpg") 
    msg.attach(part) 
       
    #pdf类型附件 
    part = MIMEApplication(open('foo.pdf','rb').read()) 
    part.add_header('Content-Disposition', 'attachment', filename="foo.pdf") 
    msg.attach(part) 
       
    #mp3类型附件 
    part = MIMEApplication(open('foo.mp3','rb').read()) 
    part.add_header('Content-Disposition', 'attachment', filename="foo.mp3") 
    msg.attach(part) 
       
    s = smtplib.SMTP("smtp.qq.com", timeout=30)#连接smtp邮件服务器,端口默认是25 
    s.login(_user, _pwd)#登陆服务器 
    s.sendmail(_user, _to, msg.as_string())#发送邮件 
    s.close()
    复制代码

    ♦有时候信息我们想进行加密传输:

    只需要在中间加上一串这样的代码举行了

    复制代码
    mail_server = smtplib.SMTP(smtp_server,25)# SMTP协议默认端口是25
    # 登陆服务器
    mail_server.ehlo()#使用ehlo指令像ESMTP(SMTP扩展)确认你的身份
    mail_server.starttls()#使SMTP连接运行在TLS模式,所有的SMTP指令都会被加密
    mail_server.ehlo()
    mail_server.set_debuglevel(1)#打印出和SMTP服务器交互的所有信息。
    mail_server.login(sender,pwd)
    # 发送邮件
    复制代码

    输出结果:

    我们厂遇到的几个坑:

      1.password:邮箱密码,163邮箱设置中的客户端授权密码

      2.msg["To"] = _to 一定要加上不然会报错。

                                              至此邮箱这块基本上就讲完了。 

    每天一点点,感受自己存在的意义。
  • 相关阅读:
    DDT驱动selenium自动化测试
    python 对Excel表格的读取
    python 对Excel表格的写入
    selenium对百度进行登录注销
    selenium的八大定位元素的方式
    selenium打开Chrome浏览器并最大化
    行列式计算的归纳
    C标准库函数getchar()
    测试必备-抓包工具的使用
    uiautomator2使用教程
  • 原文地址:https://www.cnblogs.com/liruxian/p/11208936.html
Copyright © 2011-2022 走看看