如何用python進行郵件傳送
使用Python呼叫郵件伺服器傳送郵件,使用的協議是SMTP(Simple Mail Transfer Protocol),下圖為使用TCP/IP基於SMTP傳送郵件的過程示意圖:
SMTP協議工作原理:
SMTP工作在兩種情況下:一是電子郵件從使用者端傳輸到伺服器:二是從某一個MTA(Message Transfer Agent)傳輸到另一個MTA。SMTP也是請求/響應協議,命令和響應都是基於NVT ASCII文字,並以CR和LF符結束。響應包括一個表示返回狀態的三位數字程式碼。SMTP在TCP協議25號埠監聽連續請求。
SMTP連線和傳送過程
(1)建立TCP 連線。 (2)客戶端傳送HELO命令以標識發件人自己的身份,然後客戶通過傳送MIAL命令標識出電子郵件的發起人;伺服器端正希望以OK作為響應,表明準備接收。 (3)客戶端傳送RCPT命令,以標識該電子郵件的計劃接收人,可以有多個RCPT行;伺服器端則表示是否願意為收件人接收郵件。 (4)協商結束,傳送郵件,用命令DATA傳送。 (5)以“.”號表示結束輸入內容一起傳送出去,結束此次傳送,用QUIT命令退出。Python使用SMTP傳送郵件
在python中,傳送郵件主要包括email 和smtplib,其中email 實現郵件構造,smtplib實現郵件傳送。在smtplib庫中,主要主要用smtplib.SMTP()類,用於連線SMTP伺服器,傳送郵件。SMTP類中常用方法如
方法 |
描述 |
SMTP.set_debuglevel(level) | 設定輸出debug除錯資訊,預設不輸出 |
SMTP.docmd(cmd[, argstring]) | 傳送一個命令到SMTP伺服器 |
SMTP.connect([host[, port]]) | 連線到指定的SMTP伺服器 |
SMTP.helo([hostname]) | 使用helo指令向SMTP伺服器確認你的身份 |
SMTP.ehlo(hostname) | 使用ehlo指令像ESMTP(SMTP擴充套件)確認你的身份 |
SMTP.ehlo_or_helo_if_needed() | 如果在以前的會話連線中沒有提供ehlo或者helo指令,這個方法會呼叫ehlo()或helo() |
SMTP.has_extn(name) | 判斷指定名稱是否在SMTP伺服器上 |
SMTP.verify(address) | 判斷郵件地址是否在SMTP伺服器上 |
SMTP.starttls([keyfile[, certfile]]) | 使SMTP連線執行在TLS模式,所有的SMTP指令都會被加密 |
SMTP.login(user, password) | 登入SMTP伺服器 |
SMTP.sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[]) |
傳送郵件 from_addr:郵件發件人 to_addrs:郵件收件人 msg:傳送訊息 |
SMTP.quit() | 關閉SMTP會話 |
SMTP.close() | 關閉SMTP伺服器連線 |
python中通過SMTP傳送郵件主要包括以下幾個步驟(以qq郵箱為例):
1. 開通郵箱SMTP服務,獲取郵箱授權碼,郵箱SMTP開通路徑:郵箱設定/賬戶/POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服務
2. 編輯郵件內容,主要包括三部分內容:信封,首部和正文;其中信封包括髮送郵箱,接收郵箱等;
3. 初始化配置資訊,呼叫SMTP傳送郵件
程式碼實現如下所示,其中python版本為3.7:
1 import smtplib 2 import email.utils 3 from email.mime.text import MIMEText 4 5 class Msg(): 6 def __init__(self): 7 pass 8 9 @staticmethod 10 def creat_msg(): 11 # Creat mail information 12 msg = MIMEText('Come on', 'plain', 'utf-8') 13 msg['From'] = email.utils.formataddr(('Author', '[email protected]')) 14 msg['To'] = email.utils.formataddr(('Recipient', '[email protected]')) 15 msg['Subject'] = email.utils.formataddr(('Subject', 'Good good study, day day up!')) 16 17 return msg 18 19 class EmailServer(): 20 def __init__(self): 21 pass 22 23 @staticmethod 24 def config_server(): 25 # Configure mailbox 26 config = dict() 27 config['send_email']= '[email protected]' 28 config['passwd'] = 'xxxxxxxxxx' 29 config['smtp_server'] = 'smtp.qq.com' 30 config['target_email'] = '[email protected]' 31 return config 32 33 def send_email(self): 34 # Use smtp to send email to the target mailbox 35 msg = Msg.creat_msg() 36 config = self.config_server() 37 38 server = smtplib.SMTP() 39 server.connect(host=config['smtp_server'], port=25) 40 server.login(user=config['send_email'], password=config['passwd']) 41 server.set_debuglevel(True) 42 43 try: 44 server.sendmail(config['send_email'], 45 [config['target_email']], 46 msg.as_string()) 47 finally: 48 server.quit() 49 50 if __name__ == '__main__': 51 emailServer = EmailServer() 52 emailServer.send_email()
傳送郵件過程跟蹤如下:
經過測試,從QQ郵箱向163郵箱可正常傳送郵件,從163郵箱傳送到QQ郵箱則會進入垃圾箱,翻閱了不少資料,目前還沒有解決如何擺脫垃圾箱的困擾,如有知道的朋友,可在評論區解惑,不甚感謝~
參考文獻:
(1)https://blog.51cto.com/lizhenliang/1875330
(2)TCP/IP詳解卷1:協議
&nbs