在自動化運維、數據報告推送或用户通知等場景中,通過程序自動發送郵件是一項非常實用的技能。Python 標準庫中的 smtplib 和 email 模塊提供了完整的郵件發送能力,無需第三方依賴即可實現純文本、HTML 郵件以及附件的發送。本文將帶你用不到十分鐘,掌握從基礎到進階的郵件發送技巧。
1. 基礎配置:連接SMTP服務器
大多數郵箱服務商(如 Gmail、QQ、163)都提供 SMTP 服務。以 QQ 郵箱為例,需先在設置中開啓“SMTP服務”並獲取授權碼(不是登錄密碼)。
import smtplib
from email.mime.text import MIMEText
from email.header import Header
# 郵箱配置
sender = "your_email@qq.com"
password = "your_smtp_auth_code" # 授權碼
receiver = "recipient@example.com"
smtp_server = "smtp.qq.com"
port = 465 # QQ郵箱SSL端口
2. 發送純文本郵件
使用 MIMEText 構造郵件內容,並通過 smtplib.SMTP_SSL 安全連接:
def send_text_email(subject, body):
msg = MIMEText(body, 'plain', 'utf-8')
msg['From'] = Header(sender)
msg['To'] = Header(receiver)
msg['Subject'] = Header(subject, 'utf-8')
with smtplib.SMTP_SSL(smtp_server, port) as server:
server.login(sender, password)
server.sendmail(sender, [receiver], msg.as_string())
print("郵件發送成功!")
# 使用示例
send_text_email("測試郵件", "這是一封由Python自動發送的純文本郵件。")
3. 發送HTML格式郵件
HTML 郵件支持富文本、鏈接、表格甚至內嵌樣式,適合發送美觀的報告:
from email.mime.multipart import MIMEMultipart
def send_html_email(subject, html_content):
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = receiver
msg['Subject'] = Header(subject, 'utf-8')
# 添加HTML正文
html_part = MIMEText(html_content, 'html', 'utf-8')
msg.attach(html_part)
with smtplib.SMTP_SSL(smtp_server, port) as server:
server.login(sender, password)
server.sendmail(sender, [receiver], msg.as_string())
# HTML模板示例
html = """
<h2>每日數據報告</h2>
<p>今日新增用户:<strong>1,234</strong></p>
<p>系統狀態:<span style="color:green">✅ 正常</span></p>
<a href="https://your-dashboard.com">查看詳情</a>
"""
send_html_email("【系統日報】2025-06-15", html)
4. 添加附件(圖片、PDF、Excel等)
要發送帶附件的郵件,需使用 MIMEBase 並設置正確的 Content-Type:
from email.mime.base import MIMEBase
from email import encoders
import os
def send_email_with_attachment(subject, body, file_path):
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = receiver
msg['Subject'] = Header(subject, 'utf-8')
# 添加正文
msg.attach(MIMEText(body, 'plain', 'utf-8'))
# 添加附件
with open(file_path, "rb") as f:
part = MIMEBase('application', 'octet-stream')
part.set_payload(f.read())
encoders.encode_base64(part)
part.add_header(
'Content-Disposition',
f'attachment; filename="{os.path.basename(file_path)}"'
)
msg.attach(part)
with smtplib.SMTP_SSL(smtp_server, port) as server:
server.login(sender, password)
server.sendmail(sender, [receiver], msg.as_string())
# 發送帶Excel附件的郵件
send_email_with_attachment(
"月度銷售報表",
"附件為本月銷售數據,請查收。",
"sales_report.xlsx"
)
5. 同時包含HTML正文與附件
實際應用中,常需既展示精美HTML內容,又附帶原始數據文件:
def send_rich_email(subject, html_body, attachment_path=None):
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = receiver
msg['Subject'] = Header(subject, 'utf-8')
# HTML正文
msg.attach(MIMEText(html_body, 'html', 'utf-8'))
# 可選附件
if attachment_path:
with open(attachment_path, "rb") as f:
part = MIMEBase('application', 'octet-stream')
part.set_payload(f.read())
encoders.encode_base64(part)
part.add_header(
'Content-Disposition',
f'attachment; filename="{os.path.basename(attachment_path)}"'
)
msg.attach(part)
with smtplib.SMTP_SSL(smtp_server, port) as server:
server.login(sender, password)
server.sendmail(sender, [receiver], msg.as_string())
6. 注意事項
- 授權碼安全:切勿將密碼或授權碼硬編碼在代碼中,建議使用環境變量:
import os
password = os.getenv("EMAIL_PASSWORD")
- 不同郵箱配置:
- Gmail:
smtp.gmail.com, port 465 或 587(需開啓“兩步驗證”並生成應用專用密碼); - 163郵箱:
smtp.163.com, port 465。
- 批量發送:可將
receiver改為列表,並在sendmail中傳入多個收件人。
通過 smtplib 和 email 模塊,Python 能輕鬆實現專業級的郵件自動化。無論是每日報告、異常告警還是用户註冊確認,只需幾行代碼即可完成。掌握這項技能,讓你的程序真正“會説話”。現在,就去寫一個自動發送週報的小腳本吧!