??使用Python實(shí)現(xiàn)發(fā)送Email電子郵件
??實(shí)現(xiàn)原理
-
導(dǎo)入必要的模塊:
- 導(dǎo)入
smtplib
用于處理 SMTP 功能的模塊,以及從email
模塊導(dǎo)入構(gòu)建電子郵件消息所需的各個(gè)組件。
- 導(dǎo)入
-
定義
send_email
函數(shù):- 創(chuàng)建一個(gè)名為
send_email
的函數(shù),該函數(shù)接受 SMTP 服務(wù)器詳細(xì)信息、發(fā)件人和收件人信息、主題、內(nèi)容和附件等參數(shù)。
- 創(chuàng)建一個(gè)名為
-
格式化發(fā)件人地址:
- 實(shí)現(xiàn)
_format_addr
函數(shù)以正確格式化發(fā)件人的電子郵件地址,如果提供了顯示名稱,則包含在內(nèi)。
- 實(shí)現(xiàn)
-
初始化電子郵件消息對(duì)象:
- 創(chuàng)建
MIMEMultipart
的實(shí)例,它將作為電子郵件消息的容器。
- 創(chuàng)建
-
設(shè)置發(fā)件人信息:
- 在電子郵件消息中設(shè)置發(fā)件人的信息,包括如果提供了發(fā)件人名稱則進(jìn)行設(shè)置。
-
設(shè)置收件人信息:
- 在電子郵件消息中設(shè)置收件人的信息。
-
處理抄送(CC)信息:
- 如果在 CC 列表中有收件人,則相應(yīng)地更新電子郵件消息。
-
處理密送(BCC)信息:
- 如果在 BCC 列表中有收件人,則類似于處理 CC 列表。
-
設(shè)置主題和內(nèi)容:
- 在電子郵件消息中設(shè)置主題和內(nèi)容。
-
處理附件:
- 遍歷附件列表,讀取每個(gè)文件,確定其 MIME 類型,并將其附加到電子郵件消息中。
-
嘗試連接到 SMTP 服務(wù)器并發(fā)送電子郵件:
- 嘗試使用提供的憑據(jù)連接到指定的 SMTP 服務(wù)器。
- 如果連接成功,則使用用戶名和密碼進(jìn)行登錄。
- 使用
sendmail
方法將電子郵件發(fā)送給指定的收件人。 - 關(guān)閉與 SMTP 服務(wù)器的連接。
-
處理異常:
- 實(shí)現(xiàn)異常處理以處理在過(guò)程中可能發(fā)生的錯(cuò)誤,例如文件未找到、附件讀取失敗或電子郵件發(fā)送失敗。
該實(shí)現(xiàn)涉及使用 email
模塊創(chuàng)建電子郵件消息,處理發(fā)件人和收件人信息,添加附件,并使用 smtplib
模塊連接到 SMTP 服務(wù)器并發(fā)送電子郵件。代碼被組織成一個(gè)函數(shù),以便實(shí)現(xiàn)可重用性和清晰度。
??Python實(shí)現(xiàn)發(fā)送Email電子郵件-基礎(chǔ)版
??實(shí)現(xiàn)源碼
# 導(dǎo)入smtplib模塊,這個(gè)模塊是Python的標(biāo)準(zhǔn)庫(kù),用于發(fā)送電子郵件
import smtplib
# 從email模塊中導(dǎo)入MIMEText類,這個(gè)類用于創(chuàng)建文本郵件的MIME消息對(duì)象
from email.mime.text import MIMEText
# 定義一個(gè)變量,存儲(chǔ)QQ郵箱的SMTP服務(wù)器授權(quán)碼,此授權(quán)碼用于登錄QQ郵箱SMTP服務(wù)器
secretPass = 'xxxxxxxxxxxxxxxxxx' # SMTP服務(wù)器授權(quán)碼
# 定義一個(gè)函數(shù),用于發(fā)送指定郵箱的郵件
def sendqqmail(sender_email, sender_pass, rec_email, subject, message):
# 使用MIMEText類創(chuàng)建一個(gè)郵件消息對(duì)象,其中message參數(shù)是郵件的內(nèi)容
msg = MIMEText(message)
# 設(shè)置郵件的主題
msg['Subject'] = subject
# 設(shè)置郵件的發(fā)件人郵箱
msg['From'] = sender_email
# 設(shè)置郵件的收件人郵箱
msg['To'] = rec_email
# 使用smtplib模塊的SMTP_SSL類創(chuàng)建一個(gè)SSL連接對(duì)象,連接到QQ郵箱SMTP服務(wù)器,其中'smtp.qq.com'是SMTP服務(wù)器地址,465是端口號(hào)
# 在這個(gè)類中,有兩個(gè)方法login和send_message,分別用于登錄和發(fā)送郵件
with smtplib.SMTP_SSL('smtp.qq.com', 465) as smtp:
# 使用login方法登錄SMTP服務(wù)器,參數(shù)sender_email和sender_pass分別是發(fā)件人的郵箱地址和授權(quán)碼
smtp.login(sender_email, sender_pass)
# 如果登錄成功,打印一條消息
print('登錄郵箱成功!')
# 使用send_message方法發(fā)送郵件,參數(shù)msg是要發(fā)送的郵件消息對(duì)象
smtp.send_message(msg)
# 發(fā)送成功后,打印一條消息
print('郵件發(fā)送完畢')
# 關(guān)閉SMTP服務(wù)連接
smtp.quit()
# 定義一個(gè)主函數(shù),用于運(yùn)行整個(gè)程序
def main():
# 定義發(fā)件人的郵箱地址
sender_email = 'xxxxxxxxx@qq.com' # 發(fā)信人郵箱
# 定義發(fā)件人的郵箱授權(quán)碼
emailpass = secretPass # 郵箱授權(quán)碼
# 定義收件人的郵箱地址
to_email = 'xxxxxx@xxx.com' # 收信人郵箱
# 定義郵件的主題
sub_msg = '測(cè)試python發(fā)送郵件' # 郵件主題
# 定義郵件的正文內(nèi)容
content = '這是我的第一個(gè)python發(fā)送郵件測(cè)試' # 郵件正文內(nèi)容
# 調(diào)用sendqqmail函數(shù),發(fā)送郵件
sendqqmail(sender_email, emailpass, to_email, sub_msg, content) # 發(fā)送郵件
# 執(zhí)行main函數(shù),這是Python的標(biāo)準(zhǔn)模式
if __name__ == '__main__':
main()
??源碼解析
通過(guò)SMTP協(xié)議發(fā)送郵件。
- 導(dǎo)入必要的模塊:
-
smtplib
: 用于連接SMTP服務(wù)器并發(fā)送郵件。 -
MIMEText
類:用于創(chuàng)建文本郵件的MIME消息對(duì)象。
-
import smtplib
from email.mime.text import MIMEText
- 定義了一個(gè)QQ郵箱的SMTP服務(wù)器授權(quán)碼:
secretPass = 'xxxxxxxxxxxxxxxxxx' # SMTP服務(wù)器授權(quán)碼
- 定義了一個(gè)函數(shù)
sendqqmail
,用于發(fā)送指定郵箱的郵件:- 創(chuàng)建
MIMEText
對(duì)象,設(shè)置郵件主題、發(fā)件人、收件人以及郵件內(nèi)容。 - 使用
smtplib.SMTP_SSL
創(chuàng)建一個(gè)SSL連接對(duì)象,連接到QQ郵箱SMTP服務(wù)器。 - 使用
login
方法登錄SMTP服務(wù)器。 - 使用
send_message
方法發(fā)送郵件。 - 打印登錄成功和郵件發(fā)送完畢的消息,然后關(guān)閉SMTP服務(wù)連接。
- 創(chuàng)建
def sendqqmail(sender_email, sender_pass, rec_email, subject, message):
# ...(略)
- 定義了主函數(shù)
main
:- 定義發(fā)件人、郵箱授權(quán)碼、收件人、郵件主題和郵件內(nèi)容。
- 調(diào)用
sendqqmail
函數(shù)發(fā)送郵件。
def main():
# ...(略)
- 使用
if __name__ == '__main__':
來(lái)確保代碼在作為腳本直接運(yùn)行時(shí)才會(huì)執(zhí)行main
函數(shù)。
if __name__ == '__main__':
main()
注意事項(xiàng):
- 請(qǐng)謹(jǐn)慎存儲(chǔ)和處理郵箱密碼或授權(quán)碼,不要將其硬編碼在代碼中或分享給其他人。
- 在使用SMTP服務(wù)發(fā)送郵件時(shí),需要確保你的郵箱開(kāi)啟了SMTP服務(wù),并使用了正確的SMTP服務(wù)器地址和端口號(hào)。這些信息可以從你的郵箱服務(wù)提供商獲取。
??Python實(shí)現(xiàn)發(fā)送Email電子郵件-完善版
??實(shí)現(xiàn)源碼
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.header import Header
from email.utils import parseaddr, formataddr
import mimetypes
import os
def send_email(smtp_server, username, password, sender, recipients, subject, content, cc, bcc, port=25, sendername=None, attachments=None):
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
if not attachments:
attachments = []
msg = MIMEMultipart()
if sendername:
msg['From'] = _format_addr(sendername + ' <%s>' % sender)
else:
msg['From'] = sender
if isinstance(recipients, str):
recipients = [recipients]
msg['To'] = ",".join(recipients)
if cc:
if isinstance(cc, str):
cc = [cc]
cc_list = [addr for addr in cc if addr not in recipients]
if cc_list:
msg['Cc'] = ",".join(cc_list)
recipients += cc_list
if bcc:
if isinstance(bcc, str):
bcc = [bcc]
bcc_list = [addr for addr in bcc if addr not in recipients]
if bcc_list:
msg['Bcc'] = ",".join(bcc_list)
recipients += bcc_list
msg['Subject'] = Header(subject, 'utf-8').encode()
text_part = MIMEText(content, 'html', 'utf-8')
msg.attach(text_part)
for attachment in attachments:
file_path = attachment["path"]
if not os.path.isfile(file_path):
print("附件文件不存在:{}".format(file_path))
continue
try:
with open(file_path, "rb") as f:
mime_type, encoding = mimetypes.guess_type(file_path)
if mime_type is None:
mime_type = 'application/octet-stream'
part = MIMEApplication(f.read())
part.add_header('Content-Disposition', 'attachment', filename=attachment["filename"])
part.add_header('Content-Type', mime_type)
msg.attach(part)
except FileNotFoundError as e:
print("文件未找到:{}".format(e))
except Exception as e:
print("附件讀取失?。簕}".format(e))
try:
if str(port) == "25":
server = smtplib.SMTP(smtp_server, port)
else:
server = smtplib.SMTP_SSL(smtp_server, port)
server.login(username, password)
server.sendmail(sender, recipients, msg.as_string())
server.quit()
print("郵件發(fā)送成功!")
except Exception as e:
print("郵件發(fā)送失?。簕}".format(e))
smtp_server = "smtp.aliyun.com"
username = "abc@aliyun.com"
password = "password"
sender = "abc@aliyun.com"
recipients = "abc@abc.cn"
cc = ["abc@126.com","abc@139.com"]
bcc = ""
subject = "title"
content = "content"
n = "name"
port = 25
attachments = [{"filename":"申請(qǐng)單.xlsx","path":"C:/申請(qǐng)單.xlsx"},
{"filename": "新課標(biāo).docx", "path": "D:/新課標(biāo).docx"},
{"filename": "笨笨狗.pdf", "path": "D:/books/笨笨狗.pdf"}]
send_email(smtp_server, username, password, sender, recipients, subject, content, cc,bcc,port=port, sendername=n, attachments=attachments)
??源碼解析
用于發(fā)送帶附件的郵件的 Python 腳本。
- 導(dǎo)入必要的模塊:
-
smtplib
: 用于連接SMTP服務(wù)器并發(fā)送郵件。 -
MIMEText
:創(chuàng)建文本郵件的MIME消息對(duì)象。 -
MIMEMultipart
:創(chuàng)建包含附件的MIME消息對(duì)象。 -
MIMEApplication
:用于處理附件的MIME消息對(duì)象。 -
Header
:用于對(duì)郵件頭進(jìn)行編碼。 -
parseaddr
和formataddr
:用于格式化發(fā)件人和收件人地址。 -
mimetypes
:用于猜測(cè)文件的MIME類型。 -
os
:用于處理文件路徑。
-
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.header import Header
from email.utils import parseaddr, formataddr
import mimetypes
import os
- 定義了一個(gè)發(fā)送郵件的函數(shù)
send_email
:- 使用
MIMEMultipart
創(chuàng)建一個(gè)包含附件的郵件消息對(duì)象。 - 格式化發(fā)件人和收件人地址。
- 設(shè)置郵件主題、發(fā)件人、收件人、抄送、密送。
- 將文本內(nèi)容添加到郵件中。
- 添加附件到郵件中。
- 使用
smtplib
連接到SMTP服務(wù)器,登錄,發(fā)送郵件,然后關(guān)閉連接。
- 使用
def send_email(smtp_server, username, password, sender, recipients, subject, content, cc, bcc, port=25, sendername=None, attachments=None):
# ...(略)
- 定義了一個(gè)輔助函數(shù)
_format_addr
用于格式化地址:
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
- 調(diào)用
send_email
函數(shù)發(fā)送郵件,傳遞了一些必要的參數(shù),包括SMTP服務(wù)器、發(fā)件人、收件人、郵件主題、文本內(nèi)容、抄送、密送、發(fā)件人姓名、附件等信息。
smtp_server = "smtp.aliyun.com"
username = "abc@aliyun.com"
password = "password"
sender = "abc@aliyun.com"
recipients = "abc@abc.cn"
cc = ["abc@126.com","abc@139.com"]
bcc = ""
subject = "title"
content = "content"
n = "name"
port = 25
attachments = [{"filename":"申請(qǐng)單.xlsx","path":"C:/申請(qǐng)單.xlsx"},
{"filename": "新課標(biāo).docx", "path": "D:/新課標(biāo).docx"},
{"filename": "笨笨狗.pdf", "path": "D:/books/笨笨狗.pdf"}]
send_email(smtp_server, username, password, sender, recipients, subject, content, cc,bcc,port=port, sendername=n, attachments=attachments)
??優(yōu)化
第二段代碼相對(duì)于第一段代碼進(jìn)行了一些優(yōu)化,主要體現(xiàn)在以下幾個(gè)方面:
-
支持附件:
- 第二段代碼引入了
email.mime.multipart
和email.mime.application
模塊,允許通過(guò)attachments
參數(shù)添加附件。這使得郵件可以攜帶更多類型的內(nèi)容。
- 第二段代碼引入了
-
更靈活的郵件構(gòu)建:
- 第二段代碼使用
MIMEMultipart
對(duì)象創(chuàng)建郵件消息,可以更靈活地構(gòu)建郵件內(nèi)容,包括添加文本部分、HTML部分、以及附件等。
- 第二段代碼使用
-
更友好的發(fā)件人地址:
- 引入了
_format_addr
輔助函數(shù),用于格式化發(fā)件人地址,支持設(shè)置發(fā)件人姓名。
- 引入了
-
更豐富的郵件頭信息:
- 使用
Header
對(duì)郵件主題進(jìn)行編碼,確保支持非ASCII字符的主題。 - 設(shè)置了
Content-Disposition
頭部,用于指定附件的處理方式。
- 使用
-
更全面的錯(cuò)誤處理:
- 添加了對(duì)附件文件是否存在的檢查,并輸出相應(yīng)的錯(cuò)誤信息。
- 在捕獲異常時(shí),輸出更詳細(xì)的錯(cuò)誤信息,有助于定位問(wèn)題。
-
端口號(hào)處理:
- 第二段代碼通過(guò)
str(port) == "25"
的判斷來(lái)決定使用普通 SMTP 還是 SMTP_SSL,使得端口的設(shè)置更加直觀。
- 第二段代碼通過(guò)
-
更清晰的代碼結(jié)構(gòu):
- 第二段代碼通過(guò)將不同的功能塊劃分為函數(shù),使得代碼結(jié)構(gòu)更加清晰,方便維護(hù)和閱讀。
第二段代碼在郵件功能的實(shí)現(xiàn)上更為完善,具有更多的靈活性和可讀性,并且考慮到了更多的錯(cuò)誤處理情況,使得代碼更健壯。
??總結(jié)
這兩段代碼都是用于發(fā)送郵件的簡(jiǎn)單Python腳本,但第二段代碼相對(duì)于第一段代碼進(jìn)行了一些優(yōu)化和改進(jìn)。以下是一些心得總結(jié):
-
支持附件的擴(kuò)展: 第二段代碼引入了附件的支持,使用了
email.mime.multipart
和email.mime.application
模塊,使得郵件可以攜帶更多類型的內(nèi)容,包括文本和附件。 -
更友好的發(fā)件人地址: 引入了
_format_addr
輔助函數(shù),用于格式化發(fā)件人地址,支持設(shè)置發(fā)件人姓名。這樣可以使郵件中的發(fā)件人信息更加友好和易讀。 -
更豐富的郵件頭信息: 使用
Header
對(duì)郵件主題進(jìn)行編碼,確保支持非ASCII字符的主題。同時(shí),設(shè)置了Content-Disposition
頭部,用于指定附件的處理方式,提高郵件的兼容性。 -
更全面的錯(cuò)誤處理: 第二段代碼在處理附件時(shí)增加了對(duì)附件文件是否存在的檢查,并在捕獲異常時(shí)輸出更詳細(xì)的錯(cuò)誤信息。這樣的改進(jìn)有助于提高代碼的健壯性,及時(shí)發(fā)現(xiàn)并處理潛在問(wèn)題。
-
更清晰的代碼結(jié)構(gòu): 第二段代碼通過(guò)將不同功能塊劃分為函數(shù),使得代碼結(jié)構(gòu)更清晰。這有助于提高代碼的可讀性和維護(hù)性,使每個(gè)功能單元更容易理解和修改。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-772977.html
總的來(lái)說(shuō),第二段代碼在功能實(shí)現(xiàn)上更為完善,具有更多的靈活性和可讀性,并且考慮到了更多的錯(cuò)誤處理情況,使得代碼更加健壯。在編寫(xiě)郵件發(fā)送腳本時(shí),綜合考慮郵件內(nèi)容的復(fù)雜性和錯(cuò)誤處理的全面性是很重要的。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-772977.html
到了這里,關(guān)于使用Python實(shí)現(xiàn)發(fā)送Email電子郵件【第19篇—python發(fā)郵件】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!