SMTP(Simple Mail Transfer Protocol)是簡單郵件傳輸協議,它是一組用於由源地址到目的地址的郵件傳輸規則。
python中對SMTP進行了簡單的封裝,可以發送純文本郵件,HTML郵件以及帶附件的郵件
python創建SMTP對象語法如下:
import smtplib smtpObj = smtplib.SMTP( [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模塊:負責構建郵件
- smtplib模塊:負責發送郵件
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)
1.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 = 'bmjoker@163.com' #郵箱授權碼,非登陸密碼 password = 'xxxxxxx' #收件箱地址 #receiver = '19xxxxxxx9@qq.com' mailto_list = ['19xxxxxxx9@qq.com'] #群發郵箱地址 #smtp服務器 smtp_server = 'smtp.163.com' #發送郵箱地址 msg['From'] = sender #收件箱地址 #msg['To'] = receiver 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() # 第一個參數為發送者,第二個參數為接收者,可以添加多個例如:['hello@163.com','xxx@qq.com',]# 第三個參數為發送的內容 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 = 'bmjoker@163.com' #發件郵箱 passwd = 'xxxxxxxx' #發送人郵箱授權碼 receivers = '19xxxxxxx9@qq.com' #收件郵箱 subject = 'python發郵Html郵件測試' #主題 content = "<html><h1>人生苦短,我是bmjoker</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')
emmm....遇到554/553問題居多,如果失敗,請參考smtp退信排錯:http://help.163.com/09/1224/17/5RAJ4LMH00753VB8.html
另附常見的郵箱服務器(pop3,smtp)地址,端口:
http://www.cnblogs.com/grefr/p/6089079.html
發送帶圖片的郵件:
import smtplib from email.mime.image import MIMEImage from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart sender = 'bmjoker@163.com' passwd = 'xxxxxxxx' receivers = '19xxxxxx9@qq.com' 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')
提示發送成功,不過emmm....
可能TX被APT攻擊嚇壞了吧....
發送帶附件的郵件:
import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.header import Header sender = 'bmjoker@163.com' #發件郵箱 passwd = 'xxxxxxxxxx' # 郵箱授權碼 receivers = '19xxxxxx9@qq.com' #收件郵箱 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')