一、前言
在開始正題之前,我們先理一下常見的電子郵件協議: SMTP、POP、IMAP 都遵循TCP/IP協議規范。至於Exchange是郵件服務器,不是收郵件和發郵件的協議,不要混淆概念,一般情況下不用,因為它是微軟的產品。
- SMTP:即簡單郵件傳輸協議,它是一組用於由源地址到目的地址傳送郵件的規則,由它來控制信件的中轉方式。簡單來說是 發送協議。
- POP:協議允許電子郵件客戶端下載服務器上的郵件,但是在客戶端的操作(如移動郵件、標記已讀等),不會反饋到服務器上。屬於 收件協議。
- IMAP:提供 郵件服務器 與電子郵件客戶端之間的雙向通信,客戶端的操作都會反饋到服務器上,對郵件進行的操作,服務器上的郵件也會做相應的動作(這是和POP協議主要不同點)。屬於 收件協議。
二、SMTP發送郵件
Python發送郵件比較簡單,掌握兩個自帶庫 smtplib、email 即可,使用的時候直接 import。smtplib 負責發送郵件,email 負責構造郵件(郵件內容,主題,收件人,抄送人等)。
1、發送普通郵件
1)先找到你的發送郵箱,比如我這里是企業郵箱,點擊郵箱“設置”—>“客戶端設置”,開啟 SMTP 服務器。發送服務器配置使用:smtp.exmail.qq.com(使用SSL,端口號465)
2)smtplib、email 使用如下。其中 MIMEText 構造對象時,第一個參數是郵件正文;第二個參數是subType,可以設置兩種格式 'plain' 和 'html';然后一定要指定字符編碼‘utf-8’。‘plain’ 表示發送純文本消息。
from smtplib import SMTP_SSL from email.mime.text import MIMEText def sendMail(message,Subject,sender_show,recipient_show,to_addrs,cc_show=''): ''' :param message: str 郵件內容 :param Subject: str 郵件主題描述 :param sender_show: str 發件人顯示,不起實際作用如:"xxx" :param recipient_show: str 收件人顯示,不起實際作用 多個收件人用','隔開如:"xxx,xxxx" :param to_addrs: str 實際收件人 :param cc_show: str 抄送人顯示,不起實際作用,多個抄送人用','隔開如:"xxx,xxxx" ''' # 填寫真實的發郵件服務器用戶名、密碼 user = 'root' password = '123456' # 郵件內容 msg = MIMEText(message, 'plain', _charset="utf-8") # 郵件主題描述 msg["Subject"] = Subject # 發件人顯示,不起實際作用 msg["from"] = sender_show # 收件人顯示,不起實際作用 msg["to"] = recipient_show # 抄送人顯示,不起實際作用 msg["Cc"] = cc_show with SMTP_SSL(host="smtp.exmail.qq.com",port=465) as smtp: # 登錄發郵件服務器 smtp.login(user = user, password = password) # 實際發送、接收郵件配置 smtp.sendmail(from_addr = user, to_addrs=to_addrs.split(','), msg=msg.as_string()) if __name__ =='__main': message = 'Python 測試郵件...' Subject = '主題測試' # 顯示發送人 sender_show = 'xxx' # 顯示收件人 recipient_show = 'xxx' # 實際發給的收件人 to_addrs = 'xxx@qq.com' sendMail(message,Subject,sender_show,recipient_show,to_addrs)
郵件效果:
2、發送HTML格式郵件
將 MIMEText 第二個參數設置成 'html',如:MIMEText(message, 'html', _charset="utf-8")
from smtplib import SMTP_SSL from email.mime.text import MIMEText def sendMail(message,Subject,sender_show,recipient_show,to_addrs,cc_show=''): ''' :param message: str 郵件內容 :param Subject: str 郵件主題描述 :param sender_show: str 發件人顯示,不起實際作用如:"xxx" :param recipient_show: str 收件人顯示,不起實際作用 多個收件人用','隔開如:"xxx,xxxx" :param to_addrs: str 實際收件人 :param cc_show: str 抄送人顯示,不起實際作用,多個抄送人用','隔開如:"xxx,xxxx" ''' # 填寫真實的發郵件服務器用戶名、密碼 user = 'root' password = '123456' # 郵件內容 msg = MIMEText(message, 'html', _charset="utf-8") # 郵件主題描述 msg["Subject"] = Subject # 發件人顯示,不起實際作用 msg["from"] = sender_show # 收件人顯示,不起實際作用 msg["to"] = recipient_show # 抄送人顯示,不起實際作用 msg["Cc"] = cc_show with SMTP_SSL(host="smtp.exmail.qq.com",port=465) as smtp: # 登錄發送郵件服務器 smtp.login(user = user, password = password) # 實際發送、接收郵件配置 smtp.sendmail(from_addr = user, to_addrs=to_addrs.split(','), msg=msg.as_string()) if __name__ =='__main': message = ''' <p>Python 郵件發送測試...</p> <p><a href="https://www.baidu.com">縱里尋她千百度</a></p> ''' Subject = '主題測試' # 顯示發送人 sender_show = 'xxx' # 顯示收件人 recipient_show = 'xxx' # 實際發給的收件人 to_addrs = 'xxx@qq.com' sendMail(message,Subject,sender_show,recipient_show,to_addrs)
郵件效果:
3、發送帶附件郵件
發送帶附件的郵件需借助類 MIMEMultipart(),然后構造郵件內容及附件,多個附件 attach 多次。
from smtplib import SMTP_SSL from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart def sendMail(message,Subject,sender_show,recipient_show,to_addrs,cc_show=''): ''' :param message: str 郵件內容 :param Subject: str 郵件主題描述 :param sender_show: str 發件人顯示,不起實際作用如:"xxx" :param recipient_show: str 收件人顯示,不起實際作用 多個收件人用','隔開如:"xxx,xxxx" :param to_addrs: str 實際收件人 :param cc_show: str 抄送人顯示,不起實際作用,多個抄送人用','隔開如:"xxx,xxxx" ''' # 填寫真實的發郵件服務器用戶名、密碼 user = 'root' password = '123456' # 郵件內容 msg = MIMEMultipart() msg.attach(MIMEText(message, 'html', _charset="utf-8")) # 構造附件1,傳送當前目錄下的 test.txt 文件 att = MIMEText(open('test.txt', 'rb').read(), 'base64', 'utf-8') att["Content-Type"] = 'application/octet-stream' # 附件名稱為中文時的寫法 att.add_header("Content-Disposition", "attachment", filename=("gbk", "", filename)) # 附件名稱非中文時的寫法,這里的filename可以任意寫,寫什么名字,郵件中顯示什么名字 # att["Content-Disposition"] = 'attachment; filename="{}"'.format(filename) msg.attach(att) # 郵件主題描述 msg["Subject"] = Subject # 發件人顯示,不起實際作用 msg["from"] = sender_show # 收件人顯示,不起實際作用 msg["to"] = recipient_show # 抄送人顯示,不起實際作用 msg["Cc"] = cc_show with SMTP_SSL(host="smtp.exmail.qq.com",port=465) as smtp: # 登錄發送郵件服務器 smtp.login(user = user, password = password) # 實際發送、接收郵件配置 smtp.sendmail(from_addr = user, to_addrs=to_addrs.split(','), msg=msg.as_string()) if __name__ =='__main': message = ''' <p>Python 郵件發送測試...</p> <p><a href="https://www.baidu.com">縱里尋她千百度</a></p> ''' Subject = '主題測試' # 顯示發送人 sender_show = 'xxx' # 顯示收件人 recipient_show = 'xxx' # 實際發給的收件人 to_addrs = 'xxx@qq.com' sendMail(message,Subject,sender_show,recipient_show,to_addrs)
郵件效果:
4、發送帶圖片郵件
郵件帶圖片需要用到另一個類 MIMEImage(),多張圖片 attach 多次。
from smtplib import SMTP_SSL from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.image import MIMEImage def sendMail(message,Subject,sender_show,recipient_show,to_addrs,cc_show=''): ''' :param message: str 郵件內容 :param Subject: str 郵件主題描述 :param sender_show: str 發件人顯示,不起實際作用如:"xxx" :param recipient_show: str 收件人顯示,不起實際作用 多個收件人用','隔開如:"xxx,xxxx" :param to_addrs: str 實際收件人 :param cc_show: str 抄送人顯示,不起實際作用,多個抄送人用','隔開如:"xxx,xxxx" ''' # 填寫真實的發郵件服務器用戶名、密碼 user = 'root' password = '123456' # 郵件內容 msg = MIMEMultipart() msg.attach(MIMEText(message, 'html', _charset="utf-8")) # 郵件主題描述 msg["Subject"] = Subject # 發件人顯示,不起實際作用 msg["from"] = sender_show # 收件人顯示,不起實際作用 msg["to"] = recipient_show # 抄送人顯示,不起實際作用 msg["Cc"] = cc_show # 指定圖片為當前目錄 fp = open('test.png', 'rb') msgImage = MIMEImage(fp.read()) fp.close() # 定義圖片 ID,在 HTML 文本中引用 msgImage.add_header('Content-ID', '<image>') msg.attach(msgImage) with SMTP_SSL(host="smtp.exmail.qq.com",port=465) as smtp: # 登錄發送郵件服務器 smtp.login(user = user, password = password) # 實際發送、接收郵件配置 smtp.sendmail(from_addr = user, to_addrs=to_addrs.split(','), msg=msg.as_string()) if __name__ =='__main': message = ''' <p>Python 郵件發送測試...</p> <p><a href="https://www.baidu.com">縱里尋她千百度</a></p> <p><img src="cid:image"></p> ''' Subject = '主題測試' # 顯示發送人 sender_show = 'xxx' # 顯示收件人 recipient_show = 'xxx' # 實際發給的收件人 to_addrs = 'xxx@qq.com' sendMail(message,Subject,sender_show,recipient_show,to_addrs)
郵件效果: