一、python對SMTP的支持
SMTP(Simple Mail Transfer Protocol)是簡單傳輸協議,它是一組用於用於由源地址到目的地址的郵件傳輸規則。
python中對SMTP進行了簡單的封裝,可以發送純文本郵件、HTML郵件以及帶附件的郵件。兩個核心模塊如下:
- email模塊:負責構建郵件
- smtplib模塊:負責發送郵件
python創建SMTP對象語法如下:
import smtplib
smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
# 或者
smtpObj = smtplib.SMTP_SSL( [host [, port [, local_hostname]]] )
參數說明:
host: SMTP 服務器主機。 你可以指定主機的ip地址或者域名如: runoob.com,這個是可選參數。
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 協議中定義的格式。
email模塊:支持發送的郵件內容爲純文本,HTML內容,圖片,附件。email模塊中有幾類來針對不同的郵件內容形式,常用如下:
- MIMEText : (MIME媒體類型)內容形式爲純文本,HTML頁面(導入方式 : from email.mime.text import MIMEText)
- MIMEImage : 內容形式爲圖片(導入方式 : from email.mime.image import MIMEImage)
- MIMEMultupart : 多形式組合,可包含文本和附件(導入方式 : from email.mime.multipart import MIMEMultipart)
.MIMEText語法:
MIMEText(msg,type,chartset)
msg:文本內容
type:文本類型默認爲plain(純文本)#發送HTML格式的時候,修改爲html,但同時要求msg的內容也是html的格式。
chartset:文本編碼,中文爲“utf-8”
# 構造TEXT格式的消息
msg = MIMEText("hello.text","plain","utf-8")
msg["Subject"] = "xxxxx"
msg["From"] = "xxxx"
msg["To"] = "xxxx"
# 發送以上構造的郵件內容要使用as_string將構造的郵件內容轉換爲string形式。
s.sendmail("xxx","xxx",msg.as_string)
2.MIMEImage,MIMEMultipart語法
msg = MIMEMultipart()
# 實例化一個文本對象
msg_sub = MIMEText("hello.text","plain","utf-8")
# 將text消息添加到MIMEMultipart中,作爲郵件正文。
msg.attach(msg_sub)
# 圖片作爲附件
import os
img_datas = open(os.getcwd()+ "/reports/xxxx.png","rb").read()
msg_img = MIMEImage(img_data)
msg_img.add_header('Content-Disposition','attachment', filename = "xxxx.png" )
msg_img.add_header('Content-ID','<0>')
# 將圖片添加到MIMEMultiplart中,作爲附件發送。
msg.attach(mag_img)
二、可以發送不同格式的郵件
發送文本郵件
# coding=utf-8
import smtplib
from email.mime.text import MIMEText
# 發送純文本格式的郵件
msg = MIMEText('hello,send by python_test...','plain','utf-8')
sender = '[email protected]' # 發送郵箱地址
password = 'xxxxxxx' # 郵箱授權碼,非登陸密碼
mailto_list = ['[email protected]'] # 羣發郵箱地址
smtp_server = 'smtp.163.com' # smtp服務器
msg['From'] = sender # 發送郵箱地址
msg['To'] =';'.join(mailto_list) # 發送多人郵件寫法
msg['Subject'] = 'hello,i just want to test' # 主題
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()
# 第一個參數爲發送者,第二個參數爲接收者,可以添加多個例如:['[email protected]','[email protected]',]# 第三個參數爲發送的內容
server.quit()
查看和SMTP服務器交互的所有信息:
其中login()用來登陸SMTP服務器,sendmail()用來發送郵件,羣發郵件的話,可以傳入一個收件人郵箱列表,郵箱的正文是str,使用as_string()把MIMEText對象變成str,password指的不是smtp服務器的登陸密碼,是smtp客戶端的授權密碼:
發送帶HTML的郵件:
import smtplib
from email.mime.text import MIMEText
from email.header import Header
sender = '[email protected]' # 發件郵箱
passwd = 'xxxxxxxx' # 發送人郵箱授權碼
receivers = '[email protected]' # 收件郵箱
subject = 'python發郵Html郵件測試' # 主題
content = "<html><h1>人生苦短,何必執着</h1></html>"
msg = MIMEText(content,'html','utf-8')
# msg['Subject'] = subject
msg['Subject'] = Header(subject,'utf-8')
# msg['From'] = sender
msg['From'] = Header('hello','utf-8')
# msg['To'] = receivers
msg['To'] = Header('emmmm','utf-8')
try:
s = smtplib.SMTP_SSL('smtp.163.com',25)
s.login(sender,passwd)
s.sendmail(sender,receivers,msg.as_string())
print('Send Success')
except:
print('Send Failure')
發送帶圖片附件的郵件:
import smtplib
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
sender = '[email protected]'
passwd = 'xxxxxxxx'
receivers = '[email protected]'
subject = 'python發郵帶img的郵件測試' # 主題
# 創建一個帶附件的實例
msg = MIMEMultipart()
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = receivers
# 創建正文
msg.attach(MIMEText('使用python smtplib模塊和email模塊自動發送郵件測試','plain','utf-8'))
# 創建圖片附件
import os
img_file = open(os.getcwd()+"/a4.jpg",'rb').read()
msg_img = MIMEImage(img_file)
msg_img.add_header('Content-Disposition','attachment', filename = "a4.jpg")
msg_img.add_header('Content-ID', '<0>')
msg.attach(msg_img)
try:
s = smtplib.SMTP('smtp.163.com',25)
s.set_debuglevel(1) # 輸出發送郵件詳細過程
s.login(sender,passwd)
s.sendmail(sender,receivers,msg.as_string())
print('Send Succese')
except:
print('Send Failure')
發送帶附件的郵件:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
sender = '[email protected]' # 發件郵箱
passwd = 'xxxxxxxxxx' # 郵箱授權碼
receivers = '[email protected]'# 收件郵箱
subject = 'python髮帶附件的郵件測試' # 主題
msg = MIMEMultipart() # 創建一個帶附件的實例
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = receivers
# 創建正文,將文本文件添加到MIMEMultipart中
msg.attach(MIMEText('使用python smtplib模塊和email模塊自動發送郵件測試','plain','utf-8'))
# 構造附件1,傳送當前目錄下文件
att1 = MIMEText(open('testdata.xlsx','rb').read(),'base64','utf-8') # rb以二進制方式讀取
# att1["Content-Type"] = 'application/octet-stream'
# filename爲附件名稱,可以任意寫,寫什麼名字,郵件中顯示什麼名字
att1["Content-Disposition"] = 'attachment; filename = "testdata.xlsx" '
#將附件添加到MIMEMultipart中
msg.attach(att1)
#構造附件2
att2 = MIMEText(open('db.cfg','rb').read(),'base64','utf-8')
# att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename = "db.cfg" '
#將附件添加到MIMEMultipart中
msg.attach(att2)
try:
s = smtplib.SMTP('smtp.qq.com',25)
s.set_debuglevel(1) # 輸出發送郵件詳細過程
s.login(sender,passwd)
s.sendmail(sender,receivers,msg.as_string())
print('Send Succese')
except:
print('Send Failure')
發送HTML與圖片格式的郵件
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
sender = '[email protected]' # 這裏就是你的163郵箱
receiver = '[email protected]' # 發給單人時的郵件接收郵箱
smtpserver = "smtp.163.com" # 郵件服務器,如果是163郵箱那就是這個了,其他的可以自行查找
username = '[email protected]' # 這裏還是你的郵箱
password = 'xxxxx' # 上面獲取的SMTP授權碼,相當於是一個密碼驗證
msgRoot = MIMEMultipart('related') # 郵件類型,如果要加圖片等附件,就得是這個
msgRoot['Subject'] = '監控日報' # 郵件標題,以下設置項都很明瞭
msgRoot['From'] = sender
msgRoot['To'] = receiver # 發給單人
# 以下爲郵件正文內容,含有一個居中的標題和一張圖片
content = MIMEText('<html><head><style>#string{text-align:center;font-size:25px;}</style><div id="string">我是居中顯示的標題<div></head><body><img src="cid:image1" alt="image1"></body></html>','html','utf-8')
# 如果有編碼格式問題導致亂碼,可以進行格式轉換:
# content = content.decode('utf-8').encode('gbk')
msgRoot.attach(content)
# 上面加的圖片src必須是cid:xxx的形式,xxx就是下面添加圖片時設置的圖片id
# 添加圖片附件
fp = open('D:\\Desktop\\201283116221721201.jpg', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()
msgImage.add_header('Content-ID', 'image1') # 這個id用於上面html獲取圖片
msgRoot.attach(msgImage)
'''
# 另外也可以用base64的方法直接加:
import base64
img_file = open('C:\\Users\\cloudoxou\\Desktop\\img.png','rb')
base64_data = base64.b64encode(img_file.read())
html = "<img src="data:image/png;base64,%s" alt="image1">"%(base64_data) # 這裏簡化了html代碼
'''
# 連接郵件服務器,因爲使用SMTP授權碼的方式登錄,必須是994端口
smtp = smtplib.SMTP_SSL(smtpserver,994)
smtp.login(username, password)
smtp.sendmail(sender, receiver, msgRoot.as_string())
msg中輸入的是郵件正文,因此需要根據具體內容格式選擇合適的類型!
關於不同類型文件的對應類型,可參考此鏈接:HTTP Content-type 對照表