### Python 发送多人邮件并展示收件人列表的解决方案
在使用Python进行自动化运维或日常开发工作中,常常需要通过电子邮件的方式向多个用户发送通知。但有时可能会遇到一个常见问题:发送给多个人的邮件中,收件人列表并没有正常显示出来。这不仅降低了邮件的专业度,还可能带来隐私泄露的风险。本文将详细介绍如何使用Python发送带有多个可见收件人的邮件,以解决这一问题。
#### 背景与需求
在很多场景下,如系统监控、报警通知等,我们经常需要利用Python发送邮件给不同的团队成员或者特定的用户群体。为了确保这些邮件既能准确传达信息又能保护用户的隐私,我们需要确保每个接收者只能看到自己的邮箱地址,而不会看到其他接收者的邮箱地址。此外,在某些情况下,我们还需要邮件中显示所有接收者的列表,以增强邮件的正式性和透明度。
#### 问题描述
在默认情况下,使用Python的`email`库发送邮件时,邮件客户端通常只会显示发件人信息,而不会显示收件人列表。这主要是因为Python的`email`模块默认是使用`SMTP`协议的`sendmail()`函数发送邮件,该函数只接受发件人和收件人列表,但并不会自动设置邮件头部中的`To`字段,因此在接收方的邮件客户端中通常不会显示收件人列表。
#### 解决方案
为了解决上述问题,我们需要手动设置邮件头部中的`To`字段以及其他相关信息,以便正确地显示所有收件人的邮箱地址。下面是一段示例代码:
```python
#!/usr/bin/env python
# -*-coding:utf-8-*-
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
from email.header import Header
def __format_addr__(addr):
# 解析邮件地址,以保证邮有别名可以显示
alias_name, addr = parseaddr(addr)
# 防止中文问题,进行转码处理,并格式化为str返回
return formataddr((Header(alias_name, charset="utf-8").encode(),
addr.encode("utf-8") if isinstance(addr, str) else addr))
def send_email_to(fromAddr, toAddrs, subject, html_text, filename=None):
SERVER = 'mail.***.com'
USER = '******'
PASSWD = '***'
strFrom = __format_addr__(fromAddr)
strTo = list()
# 原来是一个纯邮箱的list,现在如果是一个["jayzhen<jayzhen@jz.com>"]这样的list,给他格式化
try:
for addr in toAddrs:
strTo.append(__format_addr__(addr))
except Exception as e:
# 没有对a和toadd进行type判断,出错就直接还原
strTo = toAddrs
msgRoot = MIMEMultipart('related')
msgRoot['Subject'] = subject
msgRoot.preamble = 'This is a multi-part message in MIME format.'
msgAlternative = MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)
# 邮件对象
msgText = MIMEText(html_text, 'html', 'utf-8')
msgAlternative.attach(msgText)
# 添加附件
if filename:
with open(filename, 'rb') as f:
att5 = MIMEText(f.read(), 'base64', 'utf-8')
att5.add_header('Content-Disposition', 'attachment', filename=os.path.basename(filename))
msgRoot.attach(att5)
smtp = smtplib.SMTP(SERVER)
smtp.login(USER, PASSWD)
smtp.sendmail(strFrom, strTo, msgRoot.as_string())
smtp.quit()
return
```
#### 关键点解析
1. **格式化地址**:通过`__format_addr__`函数来解析并格式化邮件地址。这样做的目的是为了让邮件地址可以包含别名,并且能够正确处理中文字符。
2. **设置`To`字段**:在邮件头部中显式设置`To`字段,以确保邮件客户端能够正确显示所有收件人的信息。
3. **使用`MIME`类型**:通过使用`MIMEMultipart`和`MIMEText`等类来构建邮件内容,确保邮件能够正确显示HTML格式的内容以及附件。
4. **处理异常**:在处理邮件地址列表时,加入异常处理逻辑,确保即使列表中的数据格式不一致,也能尽可能地处理。
通过以上步骤,我们可以有效地解决Python发送多人邮件时无法正常显示收件人列表的问题。这种改进不仅可以提升邮件的专业度,还可以增加邮件的透明度,更好地满足业务需求。