今天嘗試實現了利用python,編寫程序來發送郵件,如下爲實現過程:python
一:關於郵件傳輸的簡介安全
SMTP (Simple Mail Transfer Protocol)
郵件傳送代理 (Mail Transfer Agent,MTA) 程序使用SMTP協議來發送電郵到接收者的郵件服務器。SMTP協議只能用來發送郵件,不能用來接收郵件。大多數的郵件發送服務器 (Outgoing Mail Server) 都是使用SMTP協議。SMTP協議的默認TCP端口號是25。服務器
SMTP協議的一個重要特色是它可以接力傳送郵件。它工做在兩種狀況下:一是電子郵件從客戶機傳輸到服務器;二是從某一個服務器傳輸到另外一個服務器。函數
POP3 (Post Office Protocol) & IMAP (Internet Message Access Protocol)
POP協議和IMAP協議是用於郵件接收的最多見的兩種協議。幾乎全部的郵件客戶端和服務器都支持這兩種協議。post
POP3協議爲用戶提供了一種簡單、標準的方式來訪問郵箱和獲取電郵。使用POP3協議的電郵客戶端一般的工做過程是:鏈接服務器、獲取全部信息並保存在用戶主機、從服務器刪除這些消息而後斷開鏈接。POP3協議的默認TCP端口號是110。ui
IMAP協議也提供了方便的郵件下載服務,讓用戶能進行離線閱讀。使用IMAP協議的電郵客戶端一般把信息保留在服務器上直到用戶顯式刪除。這種特性使得多個客戶端能夠同時管理一個郵箱。IMAP協議提供了摘要瀏覽功能,可讓用戶在閱讀完全部的郵件到達時間、主題、發件人、大小等信息後再決定是否下載。IMAP協議的默認TCP端口號是143。編碼
郵件格式 (RFC 2822)
每封郵件都有兩個部分:郵件頭和郵件體,二者使用一個空行分隔。spa
郵件頭每一個字段 (Field) 包括兩部分:字段名和字段值,二者使用冒號分隔。有兩個字段須要注意:From和Sender字段。From字段指明的是郵件的做者,Sender字段指明的是郵件的發送者。若是From字段包含多於一個的做者,必須指定Sender字段;若是From字段只有一個做者而且做者和發送者相同,那麼不該該再使用Sender字段,不然From字段和Sender字段應該同時使用。.net
郵件體包含郵件的內容,它的類型由郵件頭的Content-Type字段指明。RFC 2822定義的郵件格式中,郵件體只是單純的ASCII編碼的字符序列。debug
MIME (Multipurpose Internet Mail Extensions) (RFC 1341)
MIME擴展郵件的格式,用以支持非ASCII編碼的文本、非文本附件以及包含多個部分 (multi-part) 的郵件體等。
二:python模塊
一、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主機和端口。注意: 也能夠在host參數中指定端口號(如:smpt.yeah.net:25),這樣就不必給出port參數。
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.Python email模塊
class email.message.Message
__getitem__,__setitem__實現obj[key]形式的訪問。
Msg.attach(playload): 向當前Msg添加playload。
Msg.set_playload(playload): 把整個Msg對象的郵件體設成playload。
Msg.add_header(_name, _value, **_params): 添加郵件頭字段。
class email.mime.base.MIMEBase(_maintype, _subtype, **_params)
全部MIME類的基類,是email.message.Message類的子類。
class email.mime.multipart.MIMEMultipart()
在3.0版本的email模塊 (Python 2.3-Python 2.5) 中,這個類位於email.MIMEMultipart.MIMEMultipart。
這個類是MIMEBase的直接子類,用來生成包含多個部分的郵件體的MIME對象。
class email.mime.text.MIMEText(_text)
使用字符串_text來生成MIME對象的主體文本。
三:實例
根據以上介紹的模塊,能夠實現郵件發送的代碼以下:
(本例使用的爲163郵箱,其SMTP服務器地址爲smtp.163.com,端口號:25)
#! /usr/bin/env python
import smtplib
from email.mime.text import MIMEText
mailto_list=['xxxx@xxx.com'] #收件人(列表)
mail_host="smtp.163.com"
mail_user="name" #用戶名mail_pass="pwd"
mail_postfix="postfix"def send_mail(to_list,sub,content):
me="hello"+"<"+mail_user+"@"+mail_postfix+">"
msg = MIMEText(content,_subtype='plain')
msg['Subject'] = sub
msg['From'] = me
msg['To'] = ";".join(to_list) #將收件人列表以‘;’分隔
try:
server = smtplib.SMTP()
server.connect(mail_host)
server.login(mail_user,mail_pass)
server.sendmail(me, to_list, msg.as_string())
server.close()
return True
except Exception, e:
print str(e)
return False
for i in range(100):
if send_mail(mailto_list,"hello","haha!"): #郵件主題:hello,郵件內容:haha!print "done!" else: print "failed!"