傳統的郵件傳送相關協議主要有SMTP,POP3 及 IMAP 三種:
SMTP (Simple Mail Transfer Protocol)郵件傳送代理 (Mail Transfer Agent,MTA) 程式使用SMTP協議來發送電郵到接收者的郵件伺服器。SMTP協議只能用來發送郵件,不能用來內送郵件。大多數的郵件發送伺服器 (Outgoing Mail Server) 都是使用SMTP協議。SMTP協議的預設TCP連接埠號碼是25。
SMTP協議的一個重要特點是它能夠接力傳送郵件。它工作在兩種情況下:一是電子郵件從客戶機傳輸到伺服器;二是從某一個伺服器傳輸到另一個伺服器。
POP3(Post Office Protocol) 協議為使用者提供了一種簡單、標準的方式來訪問郵箱和擷取電郵。使用POP3協議的電郵用戶端通常的工作過程是:串連伺服器、擷取所有資訊並儲存在使用者主機、從伺服器刪除這些訊息然後中斷連線。POP3協議的預設TCP連接埠號碼是110。
IMAP (Internet Message Access Protocol)協議也提供了方便的郵件下載服務,讓使用者能進行離線閱讀。使用IMAP協議的電郵用戶端通常把資訊保留在伺服器上直到使用者顯式刪除。這種特性使得多個用戶端可以同時管理一個郵箱。IMAP協議提供了摘要瀏覽功能,可以讓使用者在閱讀完所有的郵件到達時間、主題、寄件者、大小等資訊後再決定是否下載。IMAP協議的預設TCP連接埠號碼是143。
另外,對郵件格式的要求可參考標準RFC2822 及 RFC 1341:
每封郵件都有兩個部分:郵件標頭和郵件體,兩者使用一個空行分隔。郵件標頭每個欄位 (Field) 包括兩部分:欄位名和欄位值,兩者使用冒號分隔。有兩個欄位需要注意:From和Sender欄位。From欄位指明的是郵件的作者,Sender欄位指明的是郵件的寄件者。如果From欄位包含多於一個的作者,必須指定Sender欄位;如果From欄位只有一個作者並且作者和寄件者相同,那麼不應該再使用Sender欄位,否則From欄位和Sender欄位應該同時使用。
郵件體包含郵件的內容,它的類型由郵件標頭的Content-Type欄位指明。RFC 2822定義的郵件格式中,郵件體只是單純的ASCII編碼的字元序列。MIME擴充郵件的格式,用以支援非ASCII編碼的文本、非文本附件以及包含多個部分 (multi-part) 的郵件體等。
模組介紹
Python中關於郵件發送的smtplib和email兩個模組,首先對兩個模組進行兩個簡單介紹:
1. smtplib模組
smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])
SMTP類建構函式,表示與SMTP伺服器之間的串連,通過這個串連可以向smtp伺服器發送指令,執行相關操作(如:登陸、發送郵件)。所有參數都是可選的。
host:smtp伺服器主機名稱
port:smtp服務的連接埠,預設是25;如果在建立SMTP對象的時候提供了這兩個參數,在初始化的時候會自動調用connect方法去串連伺服器。
smtplib模組還提供了SMTP_SSL類和LMTP類,對它們的操作與SMTP基本一致。
smtplib.SMTP提供的方法:
SMTP.set_debuglevel(level):設定是否為偵錯模式。預設為False,即非偵錯模式,表示不輸出任何調試資訊。
SMTP.connect([host[, port]]):串連到指定的smtp伺服器。參數分別表示smpt主機和連接埠。
SMTP.docmd(cmd[, argstring]):向smtp伺服器發送指令。選擇性參數argstring表示指令的參數。
SMTP.helo([hostname]) :使用"helo"指令向伺服器確認身份。相當於告訴smtp伺服器“我是誰”。
SMTP.has_extn(name):判斷指定名稱在伺服器郵件清單中是否存在。出於安全考慮,smtp伺服器往往屏蔽了該指令。
SMTP.verify(address) :判斷指定郵件地址是否在伺服器中存在。出於安全考慮,smtp伺服器往往屏蔽了該指令。
SMTP.login(user, password) :登陸到smtp伺服器。現在幾乎所有的smtp伺服器,都必須在驗證使用者資訊合法之後才允許發送郵件。
SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]) :發送郵件。這裡要注意一下第三個參數,msg是字串,表示郵件。我們知道郵件一般由標題,發信人,收件者,郵件內容,附件等構成,發送郵件的時候,要注意msg的格式。這個格式就是smtp協議中定義的格式。
SMTP.quit() :斷開與smtp伺服器的串連,相當於發送"quit"指令。
2. email模組
class email.mime.base.MIMEBase(_maintype, _subtype, **_params):這是MIME的一個基類。一般不需要在使用時建立執行個體。其中_maintype是內容類型,如text或者image。_subtype是內容的minor type 類型,如plain或者gif。 **_params是一個字典,直接傳遞給Message.add_header()。
class email.mime.multipart.MIMEMultipart([_subtype[, boundary[, _subparts[, _params]]]]:MIMEBase的一個子類,多個MIME對象的集合,_subtype預設值為mixed。boundary是MIMEMultipart的邊界,預設邊界是可數的。
class email.mime.application.MIMEApplication(_data[, _subtype[, _encoder[, **_params]]]):MIMEMultipart的一個子類。
class email.mime.audio. MIMEAudio(_audiodata[, _subtype[, _encoder[, **_params]]]): MIME音頻對象
class email.mime.image.MIMEImage(_imagedata[, _subtype[, _encoder[, **_params]]]):MIME二進位檔案對象。
class email.mime.message.MIMEMessage(_msg[, _subtype])
class email.mime.text.MIMEText(_text[, _subtype[, _charset]]):MIME文字物件,其中_text是郵件內容,_subtype郵件類型,可以是text/plain(普通文本郵件),html/plain(html郵件), _charset編碼,可以是gb2312等等
代碼範例:
#!/usr/bin/env python3 #coding: utf-8 import smtplib from email.mime.text import MIMEText from email.header import Header sender = '***' receiver = '***' # receiver 也可以是發送郵箱列表,sendmail將根據列表群發郵件 subject = 'python email test' smtpserver = 'smtp.163.com' username = '***' password = '***' msg = MIMEText('你好','text','utf-8')#中文需參數‘utf-8’,單位元組字元不需要 msg['Subject'] = Header(subject, 'utf-8') smtp = smtplib.SMTP() smtp.connect('smtp.163.com') smtp.login(username, password) smtp.sendmail(sender, receiver, msg.as_string()) smtp.quit()
另外還可以發送帶附件的郵件:
#!/usr/bin/env python3 #coding: utf-8 import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.image import MIMEImage sender = '***' receiver = '***' subject = 'python email test' smtpserver = 'smtp.163.com' username = '***' password = '***' msgRoot = MIMEMultipart('related') msgRoot['Subject'] = 'test message' #構造附件 att = MIMEText(open('h:\\python\\1.jpg', 'rb').read(), 'base64', 'utf-8') att["Content-Type"] = 'application/octet-stream' att["Content-Disposition"] = 'attachment; filename="1.jpg"' msgRoot.attach(att) smtp = smtplib.SMTP() smtp.connect('smtp.163.com') smtp.login(username, password) smtp.sendmail(sender, receiver, msgRoot.as_string()) smtp.quit()
zz: http://blog.csdn.net/bravezhe/article/details/7659173