smtplib --- SMTP 協(xié)議客戶端?

源代碼: Lib/smtplib.py


smtplib 模塊定義了一個(gè) SMTP 客戶端會(huì)話對(duì)象,該對(duì)象可將郵件發(fā)送到互聯(lián)網(wǎng)上任何帶有 SMTP 或 ESMTP 監(jiān)聽(tīng)程序的計(jì)算機(jī)。 關(guān)于 SMTP 和 ESMTP 操作的更多細(xì)節(jié)請(qǐng)參閱 RFC 821 (簡(jiǎn)單郵件傳輸協(xié)議) 和 RFC 1869 (SMTP 服務(wù)擴(kuò)展)。

class smtplib.SMTP(host='', port=0, local_hostname=None, [timeout, ]source_address=None)?

SMTP 實(shí)例是對(duì) SMTP 連接的封裝。 它提供了支持各種 SMTP 和 ESMTP 操作的方法。 如果給出了可選的 host 和 port 形參,則會(huì)在初始化期間調(diào)用 SMTP connect() 方法并附帶這些形參。 如果指定了 local_hostname,它將在 HELO/EHLO 命令中被用作本地主機(jī)的 FQDN。 在其他情況下,會(huì)使用 socket.getfqdn() 來(lái)找到本地主機(jī)名。 如果 connect() 調(diào)用返回了表示成功的代碼以外的信息,則會(huì)引發(fā) SMTPConnectError。 可選的 timeout 形參指定了阻塞操作如連接嘗試的超時(shí)秒數(shù)(如果未指定,則將使用全局默認(rèn)超時(shí)設(shè)置)。 如果達(dá)到超時(shí)限制,則會(huì)引發(fā) TimeoutError。 可選的 source_address 形參允許在在有多張網(wǎng)卡的計(jì)算機(jī)中綁定到某些特定的源地址,和/或綁定到某些特定的源 TCP 端口。 它接受一個(gè) 2 元組 (host, port) 作為在連接之前所綁定作為其源地址的套接字。 如果省略(或者如果 host 或 port 為 '' 和/或分別為 0)則將使用 OS 的默認(rèn)行為。

正常使用時(shí),只需要初始化或 connect 方法,sendmail() 方法,再加上 SMTP.quit() 方法即可。下文包括了一個(gè)示例。

SMTP 類支持 with 語(yǔ)句。當(dāng)這樣使用時(shí),with 語(yǔ)句一退出就會(huì)自動(dòng)發(fā)出 SMTP QUIT 命令。例如:

>>>
>>> from smtplib import SMTP
>>> with SMTP("domain.org") as smtp:
...     smtp.noop()
...
(250, b'Ok')
>>>

引發(fā)一個(gè) 審計(jì)事件 smtplib.send,附帶參數(shù) self, data。

在 3.3 版更改: 添加了對(duì) with 語(yǔ)句的支持。

在 3.3 版更改: 添加了 source_address 參數(shù)。

3.5 新版功能: 現(xiàn)在已支持 SMTPUTF8 擴(kuò)展 (RFC 6531)。

在 3.9 版更改: 如果 timeout 形參被設(shè)為零,則它將引發(fā) ValueError 來(lái)阻止創(chuàng)建非阻塞的套接字

class smtplib.SMTP_SSL(host='', port=0, local_hostname=None, keyfile=None, certfile=None, [timeout, ]context=None, source_address=None)?

SMTP_SSL 實(shí)例與 SMTP 實(shí)例的行為完全相同。在開(kāi)始連接就需要 SSL,且 starttls() 不適合的情況下,應(yīng)該使用 SMTP_SSL。如果未指定 host,則使用 localhost。如果 port 為 0,則使用標(biāo)準(zhǔn) SMTP-over-SSL 端口(465)??蛇x參數(shù) local_hostnametimeoutsource_address 的含義與 SMTP 類中的相同。可選參數(shù) context 是一個(gè) SSLContext 對(duì)象,可以從多個(gè)方面配置安全連接。請(qǐng)閱讀 安全考量 以獲取最佳實(shí)踐。

keyfilecertfilecontext 的傳統(tǒng)替代物,它們可以指向 PEM 格式的私鑰和證書鏈文件用于 SSL 連接。

在 3.3 版更改: 增加了 context。

在 3.3 版更改: 添加了 source_address 參數(shù)。

在 3.4 版更改: 本類現(xiàn)在支持使用 ssl.SSLContext.check_hostname服務(wù)器名稱指示 (參閱 ssl.HAS_SNI)進(jìn)行主機(jī)名檢查。

3.6 版后已移除: keyfilecertfile 已棄用并轉(zhuǎn)而推薦 context。 請(qǐng)改用 ssl.SSLContext.load_cert_chain() 或讓 ssl.create_default_context() 為你選擇系統(tǒng)所信任的 CA 證書。

在 3.9 版更改: 如果 timeout 形參被設(shè)為零,則它將引發(fā) ValueError 來(lái)阻止創(chuàng)建非阻塞的套接字

class smtplib.LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None[, timeout])?

LMTP 協(xié)議與 ESMTP 非常相似,它很大程度上基于標(biāo)準(zhǔn)的 SMTP 客戶端。將 Unix 套接字用于 LMTP 是很常見(jiàn)的,因此 connect() 方法支持 Unix 套接字,也支持常規(guī)的 host:port 服務(wù)器??蛇x參數(shù) local_hostname 和 source_address 的含義與 SMTP 類中的相同。要指定 Unix 套接字,host 必須使用絕對(duì)路徑,以 '/' 開(kāi)頭。

支持使用常規(guī)的 SMTP 機(jī)制來(lái)進(jìn)行認(rèn)證。 當(dāng)使用 Unix 套接字時(shí),LMTP 通常不支持或要求任何認(rèn)證,但你的情況可能會(huì)有所不同。

在 3.9 版更改: 添加了可選的 timeout 形參。

同樣地定義了一組精心選擇的異常:

exception smtplib.SMTPException?

OSError 的子類,它是本模塊提供的所有其他異常的基類。

在 3.4 版更改: SMTPException 已成為 OSError 的子類

exception smtplib.SMTPServerDisconnected?

當(dāng)服務(wù)器意外斷開(kāi)連接,或在 SMTP 實(shí)例連接到服務(wù)器之前嘗試使用它時(shí)將引發(fā)此異常。

exception smtplib.SMTPResponseException?

包括 SMTP 錯(cuò)誤代碼的所有異常的基類。 這些異常會(huì)在 SMTP 服務(wù)器返回錯(cuò)誤代碼時(shí)在實(shí)例中生成。 錯(cuò)誤代碼存放在錯(cuò)誤的 smtp_code 屬性中,并且 smtp_error 屬性會(huì)被設(shè)為錯(cuò)誤消息。

exception smtplib.SMTPSenderRefused?

發(fā)送方地址被拒絕。 除了在所有 SMTPResponseException 異常上設(shè)置的屬性,還會(huì)將 'sender' 設(shè)為代表拒絕方 SMTP 服務(wù)器的字符串。

exception smtplib.SMTPRecipientsRefused?

所有接收方地址被拒絕。 每個(gè)接收方的錯(cuò)誤可通過(guò)屬性 recipients 來(lái)訪問(wèn),該屬性是一個(gè)字典,其元素順序與 SMTP.sendmail() 所返回的一致。

exception smtplib.SMTPDataError?

SMTP 服務(wù)器拒絕接收消息數(shù)據(jù)。

exception smtplib.SMTPConnectError?

在建立與服務(wù)器的連接期間發(fā)生了錯(cuò)誤。

exception smtplib.SMTPHeloError?

服務(wù)器拒絕了我們的 HELO 消息。

exception smtplib.SMTPNotSupportedError?

嘗試的命令或選項(xiàng)不被服務(wù)器所支持。

3.5 新版功能.

exception smtplib.SMTPAuthenticationError?

SMTP 認(rèn)證出現(xiàn)問(wèn)題。 最大的可能是服務(wù)器不接受所提供的用戶名/密碼組合。

參見(jiàn)

RFC 821 - 簡(jiǎn)單郵件傳輸協(xié)議

SMTP 的協(xié)議定義。 該文件涵蓋了 SMTP 的模型、操作程序和協(xié)議細(xì)節(jié)。

RFC 1869 - SMTP 服務(wù)擴(kuò)展

定義了 SMTP 的 ESMTP 擴(kuò)展。 這描述了一個(gè)用新命令擴(kuò)展 SMTP 的框架,支持動(dòng)態(tài)發(fā)現(xiàn)服務(wù)器所提供的命令,并定義了一些額外的命令。

SMTP 對(duì)象?

一個(gè) SMTP 實(shí)例擁有以下方法:

SMTP.set_debuglevel(level)?

設(shè)置調(diào)試輸出級(jí)別。 如果 level 的值為 1 或 True ,就會(huì)產(chǎn)生連接的調(diào)試信息,以及所有發(fā)送和接收服務(wù)器的信息。 如果 level 的值為 2 ,則這些信息會(huì)被加上時(shí)間戳。

在 3.5 版更改: 添調(diào)試級(jí)別 2 。

SMTP.docmd(cmd, args='')?

向服務(wù)器發(fā)送一條命令 cmd 。 可選的參數(shù) args 被簡(jiǎn)單地串聯(lián)到命令中,用一個(gè)空格隔開(kāi)。

這將返回一個(gè)由數(shù)字響應(yīng)代碼和實(shí)際響應(yīng)行組成的2元組(多行響應(yīng)被連接成一個(gè)長(zhǎng)行)。

在正常操作中,應(yīng)該沒(méi)有必要明確地調(diào)用這個(gè)方法。它被用來(lái)實(shí)現(xiàn)其他方法,對(duì)于測(cè)試私有擴(kuò)展可能很有用。

如果在等待回復(fù)的過(guò)程中,與服務(wù)器的連接丟失, SMTPServerDisconnected 將被觸發(fā)。

SMTP.connect(host='localhost', port=0)?

連接到某個(gè)主機(jī)的某個(gè)端口。默認(rèn)是連接到 localhost 的標(biāo)準(zhǔn) SMTP 端口(25)上。如果主機(jī)名以冒號(hào) (':') 結(jié)尾,后跟數(shù)字,則該后綴將被刪除,且數(shù)字將視作要使用的端口號(hào)。如果在實(shí)例化時(shí)指定了 host,則構(gòu)造函數(shù)會(huì)自動(dòng)調(diào)用本方法。返回包含響應(yīng)碼和響應(yīng)消息的 2 元組,它們由服務(wù)器在其連接響應(yīng)中發(fā)送。

觸發(fā)一個(gè) auditing event smtplib.connect,其參數(shù)為 selfhost , port

SMTP.helo(name='')?

使用 HELO 向 SMTP 服務(wù)器表明自己的身份。 hostname 參數(shù)默認(rèn)為本地主機(jī)的完全合格域名。服務(wù)器返回的消息被存儲(chǔ)為對(duì)象的 helo_resp 屬性。

在正常操作中,應(yīng)該沒(méi)有必要明確調(diào)用這個(gè)方法。它將在必要時(shí)被 sendmail() 隱式調(diào)用。

SMTP.ehlo(name='')?

使用 EHLO 向 ESMTP 服務(wù)器表明自己的身份。 hostname 參數(shù)默認(rèn)為本地主機(jī)的完全合格域名。 檢查 ESMTP 選項(xiàng)的響應(yīng),并存儲(chǔ)它們供 has_extn() 使用。同時(shí)設(shè)置幾個(gè)信息屬性:服務(wù)器返回的消息被存儲(chǔ)為 ehlo_resp 屬性, does_esmtp 根據(jù)服務(wù)器是否支持 ESMTP 被設(shè)置為 TrueFalse ,而 esmtp_features 將是一個(gè)字典,包含這個(gè)服務(wù)器支持的 SMTP 服務(wù)擴(kuò)展的名稱,以及它們的參數(shù)(如果有)。

除非你想在發(fā)送郵件前使用 has_extn() ,否則應(yīng)該沒(méi)有必要明確調(diào)用這個(gè)方法。 它將在必要時(shí)被 sendmail() 隱式調(diào)用。

SMTP.ehlo_or_helo_if_needed()?

如果這個(gè)會(huì)話中沒(méi)有先前的 EHLOHELO 命令,該方法會(huì)調(diào)用 ehlo() 和/或 helo() 。它首先嘗試 ESMTP EHLO 。

SMTPHeloError

服務(wù)器沒(méi)有正確回復(fù) HELO 問(wèn)候。

SMTP.has_extn(name)?

如果 name 在服務(wù)器返回的 SMTP 服務(wù)擴(kuò)展集合中,返回 True ,否則為 False 。大小寫被忽略。

SMTP.verify(address)?

使用 SMTP VRFY 檢查此服務(wù)器上的某個(gè)地址是否有效。 如果用戶地址有效則返回一個(gè)由代碼 250 和完整 RFC 822 地址(包括人名)組成的元組。 否則返回 400 或更大的 SMTP 錯(cuò)誤代碼以及一個(gè)錯(cuò)誤字符串。

備注

許多網(wǎng)站都禁用 SMTP VRFY 以阻止垃圾郵件。

SMTP.login(user, password, *, initial_response_ok=True)?

登錄到一個(gè)需要認(rèn)證的 SMTP 服務(wù)器。 參數(shù)是用于認(rèn)證的用戶名和密碼。 如果會(huì)話在之前沒(méi)有執(zhí)行過(guò) EHLOHELO 命令,此方法會(huì)先嘗試 ESMTP EHLO。 如果認(rèn)證成功則此方法將正常返回,否則可能引發(fā)以下異常:

SMTPHeloError

服務(wù)器沒(méi)有正確回復(fù) HELO 問(wèn)候。

SMTPAuthenticationError

服務(wù)器不接受所提供的用戶名/密碼組合。

SMTPNotSupportedError

服務(wù)器不支持 AUTH 命令。

SMTPException

未找到適當(dāng)?shù)恼J(rèn)證方法。

smtplib 所支持的每種認(rèn)證方法只要被服務(wù)器聲明支持就會(huì)被依次嘗試。 請(qǐng)參閱 auth() 獲取受支持的認(rèn)證方法列表。 initial_response_ok 會(huì)被傳遞給 auth()

可選的關(guān)鍵字參數(shù) initial_response_ok 對(duì)于支持它的認(rèn)證方法,是否可以與 AUTH 命令一起發(fā)送 RFC 4954 中所規(guī)定的“初始響應(yīng)”,而不是要求回復(fù)/響應(yīng)。

在 3.5 版更改: 可能會(huì)引發(fā) SMTPNotSupportedError,并添加 initial_response_ok 形參。

SMTP.auth(mechanism, authobject, *, initial_response_ok=True)?

為指定的認(rèn)證機(jī)制 mechanism 發(fā)送 SMTP AUTH 命令,并通過(guò) authobject 處理回復(fù)響應(yīng)。

mechanism 指定要使用何種認(rèn)證機(jī)制作為 AUTH 命令的參數(shù);可用的值是在 esmtp_featuresauth 元素中列出的內(nèi)容。

authobject 必須是接受一個(gè)可選的單獨(dú)參數(shù)的可調(diào)用對(duì)象:

data = authobject(challenge=None)

如果可選的關(guān)鍵字參數(shù) initial_response_ok 為真值,則將先不帶參數(shù)地調(diào)用 authobject()。 它可以返回 RFC 4954 "初始響應(yīng)" ASCII str,其內(nèi)容將被編碼并使用下述的 AUTH 命令來(lái)發(fā)送。 如果 authobject() 不支持初始響應(yīng)(例如由于要求一個(gè)回復(fù)),它應(yīng)當(dāng)將 None 作為附帶 challenge=None 調(diào)用的返回值。 如果 initial_response_ok 為假值,則 authobject() 將不會(huì)附帶 None 被首先調(diào)用。

如果初始響應(yīng)檢測(cè)返回了 None,或者如果 initial_response_ok 為假值,則將調(diào)用 authobject() 來(lái)處理服務(wù)器的回復(fù)響應(yīng);它所傳遞的 challenge 參數(shù)將為一個(gè) bytes。 它應(yīng)當(dāng)返回用 base64 進(jìn)行編碼的 ASCII str data 并發(fā)送給服務(wù)器。

SMTP 類提供的 authobjects 針對(duì) CRAM-MD5, PLAINLOGIN 等機(jī)制;它們的名稱分別是 SMTP.auth_cram_md5, SMTP.auth_plainSMTP.auth_login。 它們都要求將 userpassword 這兩個(gè) SMTP 實(shí)例屬性設(shè)為適當(dāng)?shù)闹怠?/p>

用戶代碼通常不需要直接調(diào)用 auth,而是調(diào)用 login() 方法,它將按上述順序依次嘗試上述每一種機(jī)制。 auth 被公開(kāi)以便輔助實(shí)現(xiàn) smtplib 沒(méi)有(或尚未)直接支持的認(rèn)證方法。

3.5 新版功能.

SMTP.starttls(keyfile=None, certfile=None, context=None)?

將 SMTP 連接設(shè)為 TLS (傳輸層安全) 模式。 后續(xù)的所有 SMTP 命令都將被加密。 你應(yīng)當(dāng)隨即再次調(diào)用 ehlo()。

如果提供了 keyfilecertfile,它們會(huì)被用來(lái)創(chuàng)建 ssl.SSLContext。

可選的 context 形參是一個(gè) ssl.SSLContext 對(duì)象;它是使用密鑰文件和證書的替代方式,如果指定了該形參則 keyfilecertfile 都應(yīng)為 None。

如果這個(gè)會(huì)話中沒(méi)有先前的 EHLO or HELO 命令,該方法會(huì)首先嘗試 ESMTP EHLO。

3.6 版后已移除: keyfilecertfile 已棄用并轉(zhuǎn)而推薦 context。 請(qǐng)改用 ssl.SSLContext.load_cert_chain() 或讓 ssl.create_default_context() 為你選擇系統(tǒng)所信任的 CA 證書。

SMTPHeloError

服務(wù)器沒(méi)有正確回復(fù) HELO 問(wèn)候。

SMTPNotSupportedError

服務(wù)器不支持 STARTTLS 擴(kuò)展。

RuntimeError

SSL/TLS 支持在你的 Python 解釋器上不可用。

在 3.3 版更改: 增加了 context。

在 3.4 版更改: 此方法現(xiàn)在支持使用 SSLContext.check_hostname服務(wù)器名稱指示符 (參見(jiàn) HAS_SNI) 進(jìn)行主機(jī)名檢查。

在 3.5 版更改: 因缺少 STARTTLS 支持而引發(fā)的錯(cuò)誤現(xiàn)在是 SMTPNotSupportedError 子類而不是 SMTPException 基類。

SMTP.sendmail(from_addr, to_addrs, msg, mail_options=(), rcpt_options=())?

發(fā)送郵件。必要參數(shù)是一個(gè) RFC 822 發(fā)件地址字符串,一個(gè) RFC 822 收件地址字符串列表(裸字符串將被視為含有 1 個(gè)地址的列表),以及一個(gè)消息字符串。調(diào)用者可以將 ESMTP 選項(xiàng)列表(如 8bitmime)作為 mail_options 傳入,用于 MAIL FROM 命令。需要與所有 RCPT 命令一起使用的 ESMTP 選項(xiàng)(如 DSN 命令)可以作為 rcpt_options 傳入。(如果需要對(duì)不同的收件人使用不同的 ESMTP 選項(xiàng),則必須使用底層的方法來(lái)發(fā)送消息,如 mail(), rcpt()data()。)

備注

from_addrto_addrs 形參被用來(lái)構(gòu)造傳輸代理所使用的消息封包。 sendmail 不會(huì)以任何方式修改消息標(biāo)頭。

msg 可以是一個(gè)包含 ASCII 范圍內(nèi)字符的字符串,或是一個(gè)字節(jié)串。 字符串會(huì)使用 ascii 編解碼器編碼為字節(jié)串,并且單獨(dú)的 \r\n 字符會(huì)被轉(zhuǎn)換為 \r\n 字符序列。 字節(jié)串則不會(huì)被修改。

如果在此之前本會(huì)話沒(méi)有執(zhí)行過(guò) EHLOHELO 命令,此方法會(huì)先嘗試 ESMTP EHLO。 如果服務(wù)器執(zhí)行了 ESMTP,消息大小和每個(gè)指定的選項(xiàng)將被傳遞給它(如果指定的選項(xiàng)屬于服務(wù)器聲明的特性集)。 如果 EHLO 失敗,則將嘗試 HELO 并屏蔽 ESMTP 選項(xiàng)。

如果郵件被至少一個(gè)接收方接受則此方法將正常返回。 在其他情況下它將引發(fā)異常。 也就是說(shuō),如果此方法沒(méi)有引發(fā)異常,則應(yīng)當(dāng)會(huì)有人收到你的郵件。 如果此方法沒(méi)有引發(fā)異常,它將返回一個(gè)字典,其中的條目對(duì)應(yīng)每個(gè)拒絕的接收方。 每個(gè)條目均包含由服務(wù)器發(fā)送的 SMTP 錯(cuò)誤代碼和相應(yīng)錯(cuò)誤消息所組成的元組。

如果 SMTPUTF8 包括在 mail_options 中,并且被服務(wù)器所支持,則 from_addrto_addrs 可能包含非 ASCII 字符。

此方法可能引發(fā)以下異常:

SMTPRecipientsRefused

所有收件人都被拒絕。 無(wú)人收到郵件。 該異常的 recipients 屬性是一個(gè)字典,其中有被拒絕收件人的信息(類似于至少有一個(gè)收件人接受郵件時(shí)所返回的信息)。

SMTPHeloError

服務(wù)器沒(méi)有正確回復(fù) HELO 問(wèn)候。

SMTPSenderRefused

服務(wù)器不接受 from_addr。

SMTPDataError

服務(wù)器回復(fù)了一個(gè)意外的錯(cuò)誤代碼(而不是拒絕收件人)。

SMTPNotSupportedError

mail_options 中給出了 SMTPUTF8 但是不被服務(wù)器所支持。

除非另有說(shuō)明,即使在引發(fā)異常之后連接仍將被打開(kāi)。

在 3.2 版更改: msg 可以為字節(jié)串。

在 3.5 版更改: 增加了 SMTPUTF8 支持,并且如果指定了 SMTPUTF8 但是不被服務(wù)器所支持則可能會(huì)引發(fā) SMTPNotSupportedError。

SMTP.send_message(msg, from_addr=None, to_addrs=None, mail_options=(), rcpt_options=())?

本方法是一種快捷方法,用于帶著消息調(diào)用 sendmail(),消息由 email.message.Message 對(duì)象表示。參數(shù)的含義與 sendmail() 中的相同,除了 msg,它是一個(gè) Message 對(duì)象。

如果 from_addrNoneto_addrsNone,那么``send_message``將根據(jù) RFC 5322,從 msg 頭部提取地址填充下列參數(shù):如果頭部存在 Sender 字段,則用它填充 from_addr,不存在則用 From 字段填充 from_addrto_addrs 組合了 msg 中的 To, CcBcc 字段的值(字段存在的情況下)。如果一組 Resent-* 頭部恰好出現(xiàn)在 message 中,那么就忽略常規(guī)的頭部,改用 Resent-* 頭部。如果 message 包含多組 Resent-* 頭部,則引發(fā) ValueError,因?yàn)闊o(wú)法明確檢測(cè)出哪一組 Resent- 頭部是最新的。

send_message 使用 BytesGenerator 來(lái)序列化 msg,且將 \r\n 作為 linesep,并調(diào)用 sendmail() 來(lái)傳輸序列化后的結(jié)果。無(wú)論 from_addrto_addrs 的值為何,send_message 都不會(huì)傳輸 msg 中可能出現(xiàn)的 BccResent-Bcc 頭部。如果 from_addrto_addrs 中的某個(gè)地址包含非 ASCII 字符,且服務(wù)器沒(méi)有聲明支持 SMTPUTF8,則引發(fā) SMTPNotSupported 錯(cuò)誤。如果服務(wù)器支持,則 Message 將按新克隆的 policy 進(jìn)行序列化,其中的 utf8 屬性被設(shè)置為 True,且 SMTPUTF8BODY=8BITMIME 被添加到 mail_options 中。

3.2 新版功能.

3.5 新版功能: 支持國(guó)際化地址 (SMTPUTF8)。

SMTP.quit()?

終結(jié) SMTP 會(huì)話并關(guān)閉連接。 返回 SMTP QUIT 命令的結(jié)果。

與標(biāo)準(zhǔn) SMTP/ESMTP 命令 HELP, RSET, NOOP, MAIL, RCPTDATA 對(duì)應(yīng)的低層級(jí)方法也是受支持的。 通常不需要直接調(diào)用這些方法,因此它們沒(méi)有被寫入本文檔。 相關(guān)細(xì)節(jié)請(qǐng)參看模塊代碼。

SMTP 示例?

這個(gè)例子提示用戶輸入消息封包所需的地址 ('To' 和 'From' 地址),以及所要封包的消息。 請(qǐng)注意包括在消息中的標(biāo)頭必須包括在輸入的消息中;這個(gè)例子不對(duì) RFC 822 標(biāo)頭進(jìn)行任何處理。 特別地,'To' 和 'From' 地址必須顯式地包括在消息標(biāo)頭中。

import smtplib

def prompt(prompt):
    return input(prompt).strip()

fromaddr = prompt("From: ")
toaddrs  = prompt("To: ").split()
print("Enter message, end with ^D (Unix) or ^Z (Windows):")

# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\n\r\n"
       % (fromaddr, ", ".join(toaddrs)))
while True:
    try:
        line = input()
    except EOFError:
        break
    if not line:
        break
    msg = msg + line

print("Message length is", len(msg))

server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

備注

通常,你將需要使用 email 包的特性來(lái)構(gòu)造電子郵件消息,然后你可以通過(guò) send_message() 來(lái)發(fā)送它,參見(jiàn) email: 示例