- Python自動化運維快速入門
- 鄭征
- 2089字
- 2019-12-09 14:48:21
2.7 郵件提醒
郵件是互聯網上應用非常廣泛的服務,幾乎所有的編程語言都支持發送和接收電子郵件,使用Python發送郵件和接收郵件也是非常簡單易學的。現在幾乎每個人的手機上都自帶郵件客戶端,多數郵箱都支持短信提醒,因此,在運維場景中將程序報錯的信息發送到相應人員的郵箱可以及時感知程序的報錯,盡早處理從而避免更多的損失。當然,使用程序發送郵件還有許多應用場景,如網站的密碼重置等,在此不再一一列舉。
2.7.1 發送郵件
關于如何寫代碼發送郵件,我們應首先想到發送郵件使用什么協議。目前發送郵件的協議是SMTP(Simple Mail Transfer Protocol,簡單郵件傳輸協議),是一組用于由源地址到目的地址傳送郵件的規則,由它來控制信件的中轉方式。我們編寫代碼,實際上就是將待發送的消息使用SMTP協議的格式進行封裝,再提交SMTP服務器進行發送的過程。
Python內置的smtplib提供了一種很方便的途徑發送電子郵件,可以發送純文本郵件、HTML郵件及帶附件的郵件。Python對SMTP支持有smtplib和email兩個模塊,email負責構造郵件,smtplib負責發送郵件。
我們來看一下如何創建SMTP對象。Python創建SMTP對象語法如下:
import smtplib smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
參數說明:
host:SMTP服務器主機,可以指定主機的IP地址或域名,是可選參數。
port:如果提供了host參數,就需要指定SMTP服務使用的端口號,一般情況下SMTP端口號為25。
local_hostname:如果SMTP在你的本機上,那么只需要指定服務器地址為localhost即可。
Python SMTP對象使用sendmail方法發送郵件,其語法如下:
SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])
參數說明:
from_addr:郵件發送者地址。
to_addrs:字符串列表,郵件發送地址。
msg:發送消息。
第三個參數msg是字符串,表示郵件。我們知道郵件一般由標題、發信人、收件人、郵件內容、附件等組成,發送郵件時,要注意msg的格式。這個格式就是SMTP協議中定義的格式。
【示例2-29】構造簡單的文本郵件。
from email.mime.text import MIMEText message = MIMEText('Python 郵件發送測試...', 'plain', 'utf-8')
注意構造MIMEText對象時,第一個參數就是郵件正文,第二個參數是MIME的subtype,傳入plain,最終的MIME就是'text/plain',最后一定要用UTF-8編碼保證多語言兼容性。
在使用SMTP發送郵件之前,請確保所用郵箱的SMTP服務已開啟,例如163郵箱,如圖2.23所示。

圖2.23 SMTP設置方法
【示例2-30】下面使用Python發送第一封簡單的郵件(sendmail1.py)。

執行以上程序,屏幕上顯示“發送成功”的信息后,即可看到收件箱里的郵件,如圖2.24所示。

圖2.24 運行結果
讀者可能會問,可以發送HTML格式的郵件嗎?當然可以,構造正文部分修改如下:
message = MIMEText( '<html><body><h1>這是正文標題</h1>\ <p>正文內容 <a href="#">超鏈接</a>...</p>\ </body></html>', "html", "utf-8", ) # 構造正文
執行后郵件內容如圖2.25所示。

圖2.25 運行結果
到這里讀者可能會問,如何添加附件呢?請看下面的代碼:


執行以上代碼后,驗證郵箱如圖2.26所示。

圖2.26 運行結果
2.7.2 接收郵件
接收郵件的協議有POP3(Post Office Protocol)和IMAP(Internet Message Access Protocol),Python內置poplib模塊實現了POP3協議,可以直接用來接收郵件。
與SMTP協議類似,POP3協議收取的不是一個已經可以閱讀的郵件本身,而是郵件的原始文本,要把POP3收取的文本變成可以閱讀的郵件,還需要用email模塊提供的各種類來解析原始文本,變成可閱讀的郵件對象。收取郵件分以下兩步。
第一步:用poplib模塊把郵件的原始文本下載到本地。
第二步:用email模塊解析原始文本,還原為郵件對象。
【示例2-31】編寫get_mail.py來演示如何使用poplib模塊接收郵件。代碼如下:



在代碼的第64行,我們使用part0.get_content_charset()編碼來解碼郵件正文。執行上面的代碼得到如下結果。

對應的郵件截圖如圖2.27所示。

圖2.27 運行結果
2.7.3 將報警信息實時發送至郵箱
在日常運維中經常用到監控,其常用的是短信報警、郵件報警等。相比短信報警,郵件報警是一個非常低成本的解決方法,無須付給運營商短信費用,一條短信有字數限制,而郵件無此限制,因此郵件報警可以看到更多警告信息。
下面使用Python發送郵件的功能來實現報警信息實時發送至郵箱,具體需求說明如下。
(1)文本文件txt約定格式:第一行為收件人列表,以逗號分隔;第二行為主題,第三行至最后一行為正文內容,最后一行如果是文件,則作為附件發送,支持多個附件,以逗號分隔。
下面是一個完整的例子。
xxx@163.com,yyy@163.com xxx程序報警 報警信息….. ….. …… /home/log/xxx.log,/tmp/yyy.log
(2)持續監控一個目錄A下的txt文件,如果有新增或修改,則讀取文本中的內容并發送郵件。
(3)有報警需求的程序可生成(1)中格式的文本文件并傳送至目錄A即可。任意程序基本都可以實現本步驟。
現在我們就使用Python來實現上述需求,涉及的Python知識點有:文件編碼、讀文件操作、watchdog模塊應用及發送郵件。
【示例2-32】首先編寫一個發送郵件的類,其功能是解析文本文件內容并發送郵件。
文件txt2mail.py內容如下:



上述代碼實現了自定義的郵件類,功能是解析指定格式的文本文件并發送郵件,支持多個附件上傳。
接下來我們實現監控目錄的功能,使用前面學習的watchdog模塊。
文件watchDir.py內容如下:

watchdir使用watchdog模塊監控指定目錄是否有后綴為txt的文本文件,如果有新增或修改的文本文件,則調用txt2mail中的txtmail類的txt_send_mail方法;如果發送不成功則表明文本文件格式錯誤,捕捉異常是為了避免程序崩潰退出。下面我們運行測試一下。
執行python watchdir.py后的結果如圖2.28所示。

圖2.28 運行結果
在./目錄下創建一個test.txt文件,文件內容如圖2.29所示。
保存后看到運行結果如圖2.30所示。

圖2.29 運行結果

圖2.30 運行結果
登錄郵件可看到如圖2.31所示的收件信息。

圖2.31 實時郵件發送
以上基本滿足我們的日常監控需求,實際的生產環境中大家完全可以依據具體需求具體分析,這個例子也許不是最好的解決方案,但希望能起到拋磚引玉的作用。
- Python從菜鳥到高手(第2版)
- JavaScript+Vue+React全程實例
- SSM輕量級框架應用實戰
- 前端HTML+CSS修煉之道(視頻同步+直播)
- Tableau 10 Bootcamp
- C++ Application Development with Code:Blocks
- Java EE Web應用開發基礎
- Appcelerator Titanium:Patterns and Best Practices
- Python網絡爬蟲實例教程(視頻講解版)
- Extending Docker
- 菜鳥成長之路
- Mastering PostgreSQL 11(Second Edition)
- PHP編程(第4版)
- Java EE 8 Development with Eclipse
- Procedural Content Generation for Unity Game Development