python接口自動化(三十二)--Python發送郵件(常見四種郵件內容)番外篇——上(詳解)


簡介

  本篇文章與前邊沒有多大關聯,就是對前邊有關發郵件的總結和梳理。在寫腳本時,放到后台運行,想知道執行情況,會通過郵件、SMS(短信)、飛信、微信等方式通知管理員,用的最多的是郵件。在linux下,Shell腳本發送郵件告警是件很簡單的事,有現成的郵

件服務軟件或者調用運營商郵箱服務器。

  對於Python來說,需要編寫腳本調用郵件服務器來發送郵件,使用的協議是SMTP。接收郵件,使用的協議是POP3和IMAP。我想有必要說明下 ,POP3和IMAP的區別:POP3在客戶端郵箱中所做的操作不會反饋到郵箱服務器,比如刪除一封郵件,郵箱服務器並不

會刪除。IMAP則會反饋到郵箱服務器,會做相應的操作。

  Python分別提供了收發郵件的庫,smtplib、poplib和imaplib。

  本章主要講解如果使用smtplib庫實現發送各種形式的郵件內容。在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服務器連接

看下官方給的示例:

我們根據示例給自己發一個郵件測試下:

我這里測試使用本地的SMTP服務器,也就是要裝一個支持SMTP協議的服務,比如sendmail、postfix等。

CentOS安裝sendmail:yum install sendmail

1 >>> import smtplib
2 >>> s = smtplib.SMTP("localhost")
3 >>> tolist = ["xxx@qq.com", "xxx@163.com"]
4 >>> msg = '''\
5 ... From: Me@my.org
6 ... Subject: test
7 ... This is a test '''
8 >>> s.sendmail("me@my.org", tolist, msg)
9 {}

進入騰訊和網易收件人郵箱,就能看到剛發的測試郵件,一般都被郵箱服務器過濾成垃圾郵件,所以收件箱沒有,你要去垃圾箱看看。

可以看到,多個收件人可以放到一個列表中進行群發。msg對象里From表示發件人,Subject是郵件標題,換行后輸入的是郵件內容。

1.1 Python發送郵件並抄送

 1 #!/usr/bin/python
 2 # -*- coding: utf-8 -*-
 3 import smtplib
 4 def sendMail(body):
 5     smtp_server = 'smtp.163.com'
 6     from_mail = 'hongge@163.com'
 7     mail_pass = 'xxx'
 8     to_mail = ['xxx@qq.com', 'xxx@163.com']
 9     cc_mail = ['hongge@xxx.com']
10     from_name = 'monitor' 
11     subject = u'監控'.encode('gbk')   # 以gbk編碼發送,一般郵件客戶端都能識別
12 #     msg = '''\
13 # From: %s <%s>
14 # To: %s
15 # Subject: %s
16 # %s''' %(from_name, from_mail, to_mail_str, subject, body)  # 這種方式必須將郵件頭信息靠左,也就是每行開頭不能用空格,否則報SMTP 554
17     mail = [
18         "From: %s <%s>" % (from_name, from_mail),
19         "To: %s" % ','.join(to_mail),   # 轉成字符串,以逗號分隔元素
20         "Subject: %s" % subject,
21         "Cc: %s" % ','.join(cc_mail),
22         "",
23         body
24         ]
25     msg = '\n'.join(mail)  # 這種方式先將頭信息放到列表中,然后用join拼接,並以換行符分隔元素,結果就是和上面注釋一樣了
26     try:
27         s = smtplib.SMTP()
28         s.connect(smtp_server, '25')
29         s.login(from_mail, mail_pass)
30         s.sendmail(from_mail, to_mail+cc_mail, msg)   
31         s.quit()
32     except smtplib.SMTPException as e:
33         print "Error: %s" %e
34 if __name__ == "__main__":
35     sendMail("This is a test!")

s.sendmail(from_mail, to_mail+cc_mail, msg) 在這里注意下,收件人和抄送人為什么放一起發送呢?其實無論是收件人還是抄送人,它們收到的郵件都是一樣的,SMTP都是認為收件人這樣一封一封的發出。所以實際上並沒有抄送這個概念,只是在郵件頭加了抄送人的信息罷了!另外,如果不需要抄送人,直接把上面cc的信息去掉即可。

另外以上代碼發送的郵件會出現主題中文亂碼:

解決方案:三行代碼即可,修改成紅色框代碼即可

1.2 Python發送郵件帶附件

由於SMTP.sendmail()方法不支持添加附件,所以可以使用email模塊來滿足需求。email模塊是一個構造郵件和解析郵件的模塊。

先看下如何用email庫構造一個簡單的郵件:

message = Message()
message['Subject'] = '郵件主題'
message['From'] = from_mail
message['To'] = to_mail
message['Cc'] = cc_mail
message.set_payload('郵件內容')

基本的格式就是這樣的!

繼續回到主題,發送郵件帶附件:

 1 # coding=utf-8
 2 #1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行
 3 
 4 #2.注釋:包括記錄創建時間,創建人,項目名稱。
 5 '''
 6 Created on 2019-5-9
 7 @author: 北京-宏哥
 8 Project:學習和使用郵箱發帶有附件郵件
 9 '''
10 #3.導入模塊
11 import smtplib
12 from email.mime.text import MIMEText
13 from email.mime.multipart import MIMEMultipart
14 from email.header import Header
15 from email import encoders
16 from email.mime.base import MIMEBase
17 
18 def send_mail(file_new):
19     #-----------1.跟發件相關的參數------
20     smtpserver = 'smtp.mxhichina.com'                #發件服務器
21     port = 0                      #端口
22     username = 'noreply@cxx.cn'  #發件箱用戶名
23     password = 'xx@@123'        #發件箱密碼
24     sender = 'noreply@cxx.cn'    #發件人郵箱
25     receiver = ['hongge@cedex.cn','1918991791@qq.com'] #收件人郵箱
26     # ----------2.編輯郵件的內容------
27     #讀文件內容
28     f = open(file_new, 'rb')
29     mail_body = f.read()
30     f.close()
31     # 郵件正文是MIMEText
32     body = MIMEText(mail_body, 'html', 'utf-8')
33     # 郵件對象
34     msg = MIMEMultipart()
35     msg['Subject'] = Header("自動化測試報告", 'utf-8').encode()#主題
36     msg['From'] = Header(u'測試機 <%s>'%sender)                #發件人
37     msg['To'] = Header(u'測試負責人 <%s>'%receiver)            #收件人
38     msg['To'] = ';'.join(receiver)
39     msg.attach(body)
40     # # MIMEBase表示附件的對象
41     att = MIMEText(mail_body, "base64", "utf-8")
42     att["Content-Type"] = "application/octet-stream"
43     # filename是顯示附件名字
44     att["Content-Disposition"] = 'attachment; filename="test_report.html"'
45     msg.attach(att)
46     # ----------3.發送郵件------
47     try:
48         smtp = smtplib.SMTP()
49         smtp.connect(smtpserver)  # 連服務器
50         smtp.login(sender, password)
51     except:
52         smtp = smtplib.SMTP_SSL(smtpserver, port)
53         smtp.login(sender, password)  # 登錄
54     smtp.sendmail(sender, receiver, msg.as_string())  # 發送
55     smtp.quit()
56 
57 if __name__ == "__main__":
58     #本地文件的路徑
59     att_path= r'E:\pythontest\text.txt'
60     send_mail(att_path)

 

1.3 Python發送HTML郵件

 1 # coding=utf-8
 2 #1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行
 3 
 4 #2.注釋:包括記錄創建時間,創建人,項目名稱。
 5 '''
 6 Created on 2019-5-9
 7 @author: 北京-宏哥
 8 Project:學習和使用郵箱發HTML郵件
 9 '''
10 #3.導入模塊
11 #"-*- coding: utf-8 -*-"
12 import smtplib
13 from email.mime.text import MIMEText
14 
15 mail_user="XXX@163.com"
16 mail_password="******q1125"
17 mailto_list=["1918991791<1918991791@qq.com>","2014816656@qq.com"]
18 mail_host="smtp.163.com"
19 mail_postfix="163.com"
20 
21 def sendmail(to_list,sub,content):
22     me="北京-宏哥"+"<"+mail_user+"@"+mail_postfix+">"
23     msg=MIMEText("<a href='https://www.cnblogs.com/du-hong'><font color='red'>北京-宏哥</font></a>","html","utf-8")
24     msg['Subject']=sub
25     msg['From']=me
26     msg['To']=",".join(to_list)
27     try:
28         server=smtplib.SMTP()
29         server.connect(mail_host)
30         server.login(mail_user,mail_password)
31         server.sendmail(me,to_list,msg.as_string())
32         server.close()
33         return True
34     except Exception as e:
35         print (str(e))
36         return False
37 if sendmail(mailto_list,"標題:發送的是html格式","<a href='https://www.cnblogs.com/du-hong'>北京-宏哥</a>"):
38     print ("done!")
39 else:
40     print ("falsed!")

1.4 Python發送圖片郵件

# coding=utf-8
#1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行

#2.注釋:包括記錄創建時間,創建人,項目名稱。
'''
Created on 2019-5-9
@author: 北京-宏哥
Project:學習和使用1郵箱發HTML郵件
'''
#3.導入模塊
#"-*- coding: utf-8 -*-"
import smtplib
from email.mime.text import MIMEText

mail_user="@@@@@163.com"
mail_password="@@@@"
mailto_list=["1918991791<1918991791@qq.com>","2014816656@qq.com"]
mail_host="smtp.163.com"
mail_postfix="163.com"

def sendmail(to_list,sub,content):
    me="北京-宏哥"+"<"+mail_user+"@"+mail_postfix+">"
    msg=MIMEText('<html><body><img hidefocus="true" class="index-logo-src" src="//www.baidu.com/img/bd_logo1.png" width="270" height="129" usemap="#mp"></body></html>', 'html', 'utf-8')
    msg['Subject']=sub
    msg['From']=me
    msg['To']=",".join(to_list)
    try:
        server=smtplib.SMTP()
        server.connect(mail_host)
        server.login(mail_user,mail_password)
        server.sendmail(me,to_list,msg.as_string())
        server.close()
        return True
    except Exception as e:
        print (str(e))
        return False
if sendmail(mailto_list,"標題:發送的是HTML格式","<a href='https://www.cnblogs.com/du-hong'>北京-宏哥</a>"):
    print ("done!")
else:
    print ("falsed!")

上面發郵件的幾種常見的發郵件方法基本滿足日常需求了。

小結

1、linux環境下提示AttributeError: module 'smtplib' has no attribute 'SMTP',Windows環境運行代碼也報如下錯誤:

2、原因當然不是模塊的問題,檢查了一下拼寫也沒有出問題,最后在這個帖子(鏈接)的啟發下發現,發現自己的文件命名為email.py,和模塊中的函數有沖突,改名之后Linux環境郵件正常發送。


免責聲明!

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



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