本文介紹使用 Python3.6及以上通過 SMTP 協議發信。
示例代碼:
# -*- coding:utf-8 -*-
import smtplib
import email
# import json
# import base64
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# from email.mime.image import MIMEImage
# from email.mime.base import MIMEBase
# from email.mime.application import MIMEApplication
from email.header import Header
from email.utils import formataddr
# import urllib.request
# import ssl
# username,通過控制臺創建的發信地址
username = 'XXXXXXXX'
# password,通過控制臺創建的SMTP密碼
password = 'XXXXXXXX'
# 自定義的回信地址,與控制臺設置的無關。郵件推送發信地址不收信,收信人回信時會自動跳轉到設置好的回信地址。
replyto = 'XXXXXXXX'
# 顯示的To收信地址
rcptto = ['address1@example.net', 'address2@example.net']
# 顯示的Cc收信地址
rcptcc = ['address3@example.net', 'address4@example.net']
# Bcc收信地址,密送人不會顯示在郵件上,但可以收到郵件
rcptbcc = ['address5@example.net', 'address6@example.net']
# 全部收信地址,包含抄送地址,單次發送不能超過60人
receivers = rcptto + rcptcc + rcptbcc
# 構建alternative結構
msg = MIMEMultipart('alternative')
msg['Subject'] = Header('自定義信件主題')
msg['From'] = formataddr(["自定義發信昵稱", username]) # 昵稱+發信地址(或代發)
# list轉為字符串
msg['To'] = ",".join(rcptto)
msg['Cc'] = ",".join(rcptcc)
msg['Reply-to'] = replyto #用于接收回復郵件,需要收信方支持標準協議
msg['Return-Path'] = 'test@example.net' #用于接收退信郵件,需要收信方支持標準協議
msg['Message-id'] = email.utils.make_msgid() #message-id 用于唯一地標識每一封郵件,其格式需要遵循RFC 5322標準,通常如 <uniquestring@example.com>,其中uniquestring是郵件服務器生成的唯一標識,可能包含時間戳、隨機數等信息。
msg['Date'] = email.utils.formatdate()
# 若需要開啟郵件跟蹤服務,請使用以下代碼設置跟蹤鏈接頭。
# 首先域名需要備案,設置且已正確解析了CNAME配置;其次發信需要打Tag,此Tag在控制臺已創建并存在,Tag創建10分鐘后方可使用;
# 設置跟蹤鏈接頭
# tagName = 'xxxxxxx'
#
# # OpenTrace和LinkTrace的對應值是字符串'1',固定
# trace = {
# "OpenTrace": '1', #打開郵件跟蹤
# "LinkTrace": '1', #點擊郵件里的URL跟蹤
# "TagName": tagName # 控制臺創建的標簽tagname
# }
# jsonTrace = json.dumps(trace)
# base64Trace = str(base64.b64encode(jsonTrace.encode('utf-8')), 'utf-8')
# # print(base64Trace)
# msg.add_header("X-AliDM-Trace", base64Trace)
# 構建alternative的text/plain部分
# textplain = MIMEText('自定義TEXT純文本部分', _subtype='plain', _charset='UTF-8')
# msg.attach(textplain)
# 構建alternative的text/html部分
texthtml = MIMEText('自定義HTML超文本部分', _subtype='html', _charset='UTF-8')
msg.attach(texthtml)
# # 發送本地附件
# files = [r'C:\Users\Downloads\test1.jpg', r'C:\Users\Downloads\test2.jpg']
# for t in files:
# filename = t.rsplit('/', 1)[1]
# part_attach1 = MIMEApplication(open(t, 'rb').read()) # 打開附件
# part_attach1.add_header('Content-Disposition', 'attachment', filename=filename) # 為附件命名
# msg.attach(part_attach1) # 添加附件
# #發送url附件
# files = [r'https://example.oss-cn-shanghai.aliyuncs.com/xxxxxxxxxxx.png']
# for t in files:
# filename=t.rsplit('/', 1)[1]
# response = urllib.request.urlopen(t)
# part_attach1 = MIMEApplication(response.read()) # 打開附件,非本地文件
# part_attach1.add_header('Content-Disposition', 'attachment', filename=filename) # 為附件命名
# msg.attach(part_attach1) # 添加附件
# 發送郵件
try:
# 若需要加密使用SSL,可以這樣創建client
# client = smtplib.SMTP_SSL('smtpdm.aliyun.com', 465)
# python 3.10/3.11新版本若出現ssl握手失敗,請使用下列方式處理:
# ctxt = ssl.create_default_context()
# ctxt.set_ciphers('DEFAULT')
# client = smtplib.SMTP_SSL('smtpdm.aliyun.com', 465, context=ctxt)
# SMTP普通端口為25或80
client = smtplib.SMTP('smtpdm.aliyun.com', 80)
# 開啟DEBUG模式
client.set_debuglevel(0)
# 發件人和認證地址必須一致
client.login(username, password)
# 備注:若想取到DATA命令返回值,可參考smtplib的sendmail封裝方法:
# 使用SMTP.mail/SMTP.rcpt/SMTP.data方法
# print(receivers)
client.sendmail(username, receivers, msg.as_string()) # 支持多個收件人,具體數量參考規格清單
client.quit()
print('郵件發送成功!')
except smtplib.SMTPConnectError as e:
print('郵件發送失敗,連接失敗:', e.smtp_code, e.smtp_error)
except smtplib.SMTPAuthenticationError as e:
print('郵件發送失敗,認證錯誤:', e.smtp_code, e.smtp_error)
except smtplib.SMTPSenderRefused as e:
print('郵件發送失敗,發件人被拒絕:', e.smtp_code, e.smtp_error)
except smtplib.SMTPRecipientsRefused as e:
print('郵件發送失敗,收件人被拒絕:', e.smtp_code, e.smtp_error)
except smtplib.SMTPDataError as e:
print('郵件發送失敗,數據接收拒絕:', e.smtp_code, e.smtp_error)
except smtplib.SMTPException as e:
print('郵件發送失敗, ', str(e))
except Exception as e:
print('郵件發送異常, ', str(e))
文檔內容是否對您有幫助?