說說如何使用 Python 發送電子郵件

使用 Python 的 smtplib 模塊,就可以實現發送郵件。

1 電子郵件服務器

如果是網易 163 郵箱,我們可以在瀏覽器中登陸 https://mail.163.com/ 郵箱後,依次點擊 設置 → POP3/SMTP/IMAP ,進入服務器設置頁:

進入服務器設置頁後,確保開啓 SMTP 與 IMAP 服務。設置頁的最下面就是網易郵箱的服務器地址:

(1)SMTP

發送電子郵件使用的協議是簡單郵件傳輸協議( SMTP ,Simple Mail Transfer Protocol)。它是一種提供可靠且有效的電子郵件傳輸的協議。 SMTP 是建立在 FTP 文件傳輸服務上的一種郵件服務,主要用於系統之間的郵件信息傳遞,並提供有關來信的通知。 SMTP 獨立於特定的傳輸子系統,且只需要可靠有序的數據流信道支持, SMTP 的重要特性之一是其能跨越網絡傳輸郵件,即“ SMTP 郵件中繼 ”。 使用 SMTP ,可實現相同網絡處理進程之間的郵件傳輸,也可通過中繼器或網關實現某處理進程與其他網絡之間的郵件傳輸。

(2)IMAP

IMAP(Internet Mail Access Protocol)以前稱作交互郵件訪問協議(Interactive Mail Access Protocol),是一個應用層協議。IMAP是斯坦福大學在1986年開發的一種郵件獲取協議。它的主要作用是郵件客戶端可以通過這種協議從郵件服務器上獲取郵件的信息,下載郵件等。當前的權威定義是RFC3501。IMAP協議運行在TCP/IP協議之上,使用的端口是143。

(3)POP3

POP3,全名爲“Post Office Protocol - Version 3”,即“郵局協議版本3”。是TCP/IP協議族中的一員,由RFC1939 定義。本協議主要用於支持使用客戶端遠程管理在服務器上的電子郵件。提供了SSL加密的POP3協議被稱爲POP3S。

POP 協議支持 “ 離線 ” 郵件處理。其具體過程是:郵件發送到服務器上,電子郵件客戶端調用郵件客戶機程序以連接服務器,並下載所有未閱讀的電子郵件。這種離線訪問模式是一種存儲轉發服務,將郵件從郵件服務器端送到個人終端機器上,一般是 PC 機或 MAC 。 一旦郵件發送到 PC 機或 MAC 上,郵件服務器上的郵件將會被刪除。但 POP 3郵件服務器大都可以 “ 只下載郵件,服務器端並不刪除 ” ,也就是改進的 POP 3協議。


IMAP 與 POP3 協議的主要區別是用戶可以不用把所有的郵件全部下載,可以通過客戶端直接對服務器上的郵件進行操作。所以相對來說,IMAP 協議更先進。

2 發送電子郵件

(1)創建 SMTP 對象

首先創建一個 SMTP 對象,入參爲 163 郵箱地址與端口號:

smtp_obj = smtplib.SMTP('smtp.163.com', 25);

(2)建立連接

response = smtp_obj.ehlo()
logging.info('ehlo() -> %s', response)

運行結果:

INFO - ehlo() -> (250, b'mail\nPIPELINING\nAUTH LOGIN PLAIN\nAUTH=LOGIN PLAIN\ncoremail xxx\nSTARTTLS\n8BITMIME')

得到 SMTP 對象後,調用 ehlo() 方法,連接 SMTP 電子郵件服務器, 也就是 “ 打招呼 ”๑乛◡乛๑。

250 就表示連接成功。

SMTP 協議有以下這些響應碼,每個響應碼的具體說明如下:

響應碼 說明
501 參數格式錯誤
502 命令不可實現
503 錯誤的命令序列
504 命令參數不可實現
211 系統狀態或系統幫助響應
214 幫助信息
220 <domain>服務就緒
221 <domain>服務關閉
421 <domain>服務未就緒,關閉傳輸信道
250 操作完成
251 用戶非本地,將轉發到<forward-path>
450 要求的操作未完成,收信端無此賬戶
550 要求的操作未完成,郵箱不可用
451 放棄要求的操作;處理過程中出錯
551 用戶非本地,請嘗試<forward-path>
452 系統存儲不足,要求的操作未執行
552 過量的存儲分配,要求的操作未執行
553 郵箱名不可用,要求的操作未執行
554 操作失敗

(3)TLS 加密

網易郵箱的 POP3/SMTP/IMAP 服務全部支持 SSL 連接。

安全傳輸層協議(TLS)用於在兩個通信應用程序之間提供保密性和數據完整性。

傳輸層安全性協議( Transport Layer Security ,縮寫作 TLS ),及其前身安全套接層( Secure Sockets Layer ,縮寫作 SSL )是一種安全協議,目的是爲互聯網通信提供安全及數據完整性保障。網景公司( Netscape )在 1994 年推出首版網頁瀏覽器,網景導航者時,推出 HTTPS 協議,以 SSL 進行加密,這是 SSL 的起源 。IETF 將 SSL 進行標準化, 1999 年公佈第一版 TLS 標準文件。隨後又公佈 RFC5246 ( 2008 年8月)與 RFC6176 ( 2011 年3月)。在瀏覽器 、 郵箱 、 即時通信 、 VoIP 、 網絡傳真等應用程序中,廣泛支持這個協議。主要的網站,如Google 、 Facebook等也以這個協議來創建安全連線,發送數據。目前已成爲互聯網上保密通信的工業標準。

response = smtp_obj.starttls()
logging.info('starttls() -> %s\n', response)

運行結果:

INFO - starttls() -> (220, b'Ready to start TLS')

響應碼 220 表示服務器已開啓 TLS 加密模式。

(4)登陸 SMTP 服務器

建立 TLS 加密連接後,就可以調用 login() 方法,用郵箱賬戶名與密碼進行登錄操作。建議使用 input() ,在程序運行時輸入密碼。這樣做的好處是,避免因爲源代碼泄露,導致密碼外泄。

email_address = [email protected]'
pwd = input('please input your password:')

response = smtp_obj.login(email_address, pwd)
logging.info('\nlogin() -> %s', response)

運行結果:

please input your password:> xxx
INFO - 
login() -> (235, b'Authentication successful')

login 方法接收賬號與密碼作爲入參。這裏返回 235 表示認證成功。如果密碼不正確, Python 會拋出 smtplib.SMTPAuthenticationError 異常。

(5)定義發送內容

msg = MIMEMultipart()
msg["From"] = email_address
to_mail_address = [email protected]'
msg['To'] = to_mail_address
msg['Subject'] = '確認《Spring Cloud微服務架構》'
content = MIMEText('收到這本書後,<b>請回復下</b>', 'html', 'utf-8')
msg.attach(content)

先創建 MIMEMultipart 對象,然後定義以下內容:

說明
From 發送端郵箱地址。
To 接收端郵箱地址。
Subject 郵箱標題。
content 郵箱內容,HTML 格式。

(6)發送郵件

response = smtp_obj.sendmail(email_address, to_mail_address, msg.as_string())
logging.info('sendmail() -> %s', response)

運行結果:

INFO - sendmail() -> {}

然後調用 sendmail()方法來發送電子郵件。 sendmail() 的返回值是一個字典類型。如果發送失敗,那麼該字典就會返回包含失敗收件人的鍵值對信息;如果發送成功,那麼該字典爲空。

(7)斷開連接

response = smtp_obj.quit()
logging.info('quit() -> %s', response)

運行結果:

INFO - quit() -> (221, b'Bye')

發送電子郵件後,調用 quit()方法,斷開與 SMTP 服務器的連接。 響應碼 221 表示會話結束。


完整示例如下:

import logging
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

logging.basicConfig(level=logging.DEBUG, format='%(levelname)s - %(message)s')

'''
send email
@author Deniro Lee
'''
print('$$$')
smtp_obj = smtplib.SMTP('smtp.163.com', 25);
response = smtp_obj.ehlo()
logging.info('ehlo() -> %s', response)
response = smtp_obj.starttls()
logging.info('starttls() -> %s\n', response)

email_address = [email protected]'
pwd = input('please input your password:')

response = smtp_obj.login(email_address, pwd)
logging.info('\nlogin() -> %s', response)

msg = MIMEMultipart()
msg["From"] = email_address
to_mail_address = [email protected]'
msg['To'] = to_mail_address
msg['Subject'] = '確認《Spring Cloud微服務架構》'
content = MIMEText('收到這本書後,<b>請回復下</b>', 'html', 'utf-8')
msg.attach(content)

response = smtp_obj.sendmail(email_address, to_mail_address, msg.as_string())
logging.info('sendmail() -> %s', response)

response = smtp_obj.quit()
logging.info('quit() -> %s', response)

運行結果:

INFO - ehlo() -> (250, b'mail\nPIPELINING\nAUTH LOGIN PLAIN\nAUTH=LOGIN PLAIN\ncoremail xxx\nSTARTTLS\n8BITMIME')
INFO - starttls() -> (220, b'Ready to start TLS')
please input your password:> xxx
INFO - 
login() -> (235, b'Authentication successful')
INFO - sendmail() -> {}
INFO - quit() -> (221, b'Bye')

打開發送目標郵箱後,就會看到剛剛發出的這封郵件:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章