如何使用Python將生成的測試報告以郵件附件的形式進行發送呢?
一、概要
SMTP(Simple Mail Transfer Protocol)即簡單郵件傳輸協議,它是一組用於由源地址到目的地址傳送郵件的規則,由它來控制信件的中轉方式。
python的smtplib提供了一種很方便的途徑發送電子郵件,它對smtp協議進行了簡單的封裝。
Python對SMTP支持有smtplib
和email
兩個模塊。其中email
負責構造郵件,smtplib
則負責發送郵件。
來理一理Python發送一個未知MIME類型的文件附件基本思路:
0、前提:導入郵件發送模塊
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib
1、構造MIMEMultipart對象作爲根容器
2、構造MIMEText對象作爲郵件顯示內容並附加到根容器
a、讀入文件內容並格式化
b、設置附件頭
3、設置根容器屬性
4、得到格式化後的完整文本
5、用smtp發送郵件
6、封裝成sendEmail類。
二、郵件發送要素
同時想想我們要發送郵件的幾個要素:
1、服務器。以QQ郵箱舉例,則爲smtp.qq.com
2、端口號。有465和587,請使用587
3、發送者。
4、密碼。密碼總不能直接寫在文件裏吧?哈哈,這裏需要使用qq郵箱獲取授權碼。
5、收件人。(可能還不止一個)
6、發送郵件的主題subject。
7、郵件文本內容。
8、附件。
因爲之前寫過如何讀取.ini配置文件,所以此部分,將發送郵件的一些要素放在了配置文件中,配置文件如下:
對應讀取配置文件腳本爲:(readConfig.py部分)
import os
import configparser
# config
cur_path = os.path.dirname(os.path.relpath(__file__))
configPath = os.path.join(cur_path,'config.ini')
conf = configparser.ConfigParser()
conf.read(configPath)
def get_smtpServer(smtpServer):
smtp_server = conf.get('email',smtpServer)
return smtp_server
#
......
三、郵件部分
構建MIMEMultipart()郵件根容器對象後,需要藉助根容器來定義郵件的各個要素,比如郵件主題subject、發送人from、接收人to、郵件正文body、郵件附件等。
如何給郵件定主題、收發人呢?
# 構建根容器
msg = MIMEMultipart()
# 郵件主題、發送人、收件人、內容,此部分可以來自配置文件,也可以直接填入
msg['Subject'] = self.mail_subject # u'自動化測試報告'
msg['from'] = self.mail_sender
msg['to'] = self.mail_pwd
如何定義郵件正文body部分呢?
# 郵件正文部分body,1、可以用HTML自己自定義body內容;2、讀取其他文件的內容爲body
# body = "您好,<p>這裏是使用Python登錄郵箱,併發送附件的測試<\p>"
with open(reportFile,'r',encoding='UTF-8') as f:
body = f.read()
msg.attach(MIMEText(_text=body, _subtype='html', _charset='utf-8')) # _charset 是指Content_type的類型
如何給郵件添加附件呢?
# 添加附件
attachment = MIMEText(_text=open(reportFile, 'rb').read(), _subtype='base64',_charset= 'utf-8')
attachment['Content-Type'] = 'application/octet-stream'
attachment['Content-Disposition'] = 'attachment;filename = "result.html"'
msg.attach(attachment)
如何發送?
發送四部曲:取得服務器連接、再登錄郵箱、發送郵件、退出。
大致如下啦:
try:
smtp = smtplib.SMTP_SSL(host=self.mail_smtpserver, port=self.mail_port) # 繼承自SMTP
except:
smtp = smtplib.SMTP()
smtp.connect(self.mail_smtpserver, self.mail_port)
# smtp.set_debuglevel(1)
# 創建安全連接,加密SMTP
smtp.starttls() # Puts the connection to the SMTP server into TLS mode.
# 用戶名和密碼
smtp.login(user=self.mail_sender, password=self.mail_pwd)
# 函數:sendmail(self, from_addr, to_addrs, msg, mail_options=[],rcpt_options=[]):
smtp.sendmail(self.mail_sender, self.mail_receiverList, msg.as_string())
smtp.quit()
在裏面添加了一句smtp.starttls()
。這一句是用來加密SMTP會話,保證郵件安全發送不被竊聽的。
在創建完SMTP對象後,立刻調用starttls()
方法即可。
其實整個下來郵件發送模塊也就完成了。
四、問題
在這個過程中有遇見幾個問題,也貼上來跟大家一起分享一下。
- 拋錯535
拋錯:smtplib.SMTPAuthenticationError: (535, b'Error: xc7xebxcaxb9xd3xc3xcaxdaxc8xa8xc2xebxb5xc7xc2xbcxa1xa3xcfxeaxc7xe9xc7xebxbfxb4: http://service.mail.qq.com/cg...')
解決辦法:點擊最後的鏈接,其實是因爲授權碼問題 - 替換授權碼後繼續報錯,535
解決辦法:替換端口。因爲qq郵箱ssl協議端口有兩個:465/587。 - 報錯:smtplib.SMTPAuthenticationError: (530, b'Must issue a STARTTLS command first.')
解決方法:在login()之前,添加一句:smtp.starttls()
五、代碼all
下面貼上整個文件,這個文件是依賴於其他文件的的,所以僅供參考,但是方法是一樣的。
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
class SendEmail(object):
'''
發送郵件模塊封裝,屬性均從config.ini文件獲得
'''
def __init__(self, smtpServer, mailPort, mailSender, mailPwd, mailtoList, mailSubject):
self.mail_smtpserver = smtpServer
self.mail_port = mailPort
self.mail_sender = mailSender
self.mail_pwd = mailPwd
# 接收郵件列表
self.mail_receiverList = mailtoList
self.mail_subject = mailSubject
# self.mail_content = mailContent
def sendFile(self, reportFile):
'''
發送各種類型的附件
'''
# 構建根容器
msg = MIMEMultipart()
# 郵件正文部分body,1、可以用HTML自己自定義body內容;2、讀取其他文件的內容爲body
# body = "您好,<p>這裏是使用Python登錄郵箱,併發送附件的測試<\p>"
with open(reportFile,'r',encoding='UTF-8') as f:
body = f.read()
# _charset 是指Content_type的類型
msg.attach(MIMEText(_text=body, _subtype='html', _charset='utf-8'))
# 郵件主題、發送人、收件人、內容
msg['Subject'] = self.mail_subject # u'自動化測試報告'
msg['from'] = self.mail_sender
msg['to'] = self.mail_pwd
# 添加附件
attachment = MIMEText(_text=open(reportFile, 'rb').read(), _subtype='base64',_charset= 'utf-8')
attachment['Content-Type'] = 'application/octet-stream'
attachment['Content-Disposition'] = 'attachment;filename = "result.html"'
msg.attach(attachment)
try:
smtp = smtplib.SMTP_SSL(host=self.mail_smtpserver, port=self.mail_port) # 繼承自SMTP
except:
smtp = smtplib.SMTP()
smtp.connect(self.mail_smtpserver, self.mail_port)
# smtp.set_debuglevel(1)
# 創建安全連接,加密SMTP
smtp.starttls() # Puts the connection to the SMTP server into TLS mode.
# 用戶名和密碼
smtp.login(user=self.mail_sender, password=self.mail_pwd)
# 函數:sendmail(self, from_addr, to_addrs, msg, mail_options=[],rcpt_options=[]):
smtp.sendmail(self.mail_sender, self.mail_receiverList, msg.as_string())
smtp.quit()
# 調試代碼
if __name__ == "__main__":
mail_smtpserver = 'smtp.qq.com'
mail_port = 587
mail_sender = '@qq.com'
mail_pwd = ''
mail_receiverList = ['@qq.com', '@163.com']
mail_subject = u'自動化測試報告'
s = SendEmail(mail_smtpserver, mail_port, mail_sender, mail_pwd, mail_receiverList, mail_subject)
s.sendFile('F:\Python_project\PythonLearnning_2018\send_email\sendEmail_Test.html.tar.gz')
print('--- test end --- ')
如果覺得文章有丟丟用處,動動小指,點個贊吧!
如果哪裏寫的有問題,或者有更好的方式,cue我一下
❤ thanks for watching, keep on updating...