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 一定要加上不然會報錯。

                                          至此郵箱這塊基本上就講完了。 

每天一點點,感受自己存在的意義。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM