Python发送邮件至Outlook带!前缀通讯组列表失效问题咨询
问题根源
你看到的带!前缀的通讯组地址不是标准SMTP协议支持的合法邮箱地址,这是Outlook客户端对Exchange通讯组做的本地别名展示,仅能在Outlook客户端界面内被解析,SMTP服务器根本识别不了这种带特殊前缀的地址,直接传当然会发送失败。
另外你现有代码本身还有个隐藏bug:
recipients = ['someone@company.com, someonelse@company.com'] emaillist = [elem.strip().split(',') for elem in recipients]
这段逻辑生成的emaillist是嵌套列表[['someone@company.com', 'someonelse@company.com']],而smtplib.SMTP.sendmail()要求收件人参数是一维字符串列表,之前发个人邮箱没报错只是巧合,必须先修正这个逻辑。
解决方案
按优先级从高到低试:
方案1:使用通讯组的真实SMTP地址(90%场景可用)
公司IT维护的所有Exchange通讯组,都有一个不带!前缀的标准SMTP投递地址,通常就是你看到的别名去掉开头的!,比如!groupdept@company.com对应的真实地址一般是groupdept@company.com。
- 验证方法:手动在Outlook里给这个带
!的组发一封测试邮件,发完打开已发送文件夹里的这封邮件,查看原始邮件头/收件人字段的真实地址,就能拿到不带!的标准投递地址,直接把这个地址放到收件人列表里即可。
方案2:修正SMTP认证逻辑
如果用真实地址还是发失败,大概率是通讯组开启了发信权限限制,只允许公司域内认证用户发送,你现在用25端口匿名连接的方式会被拒。改成587端口配合STARTTLS加密、用你的公司域账号认证后再发即可,修正后的完整代码参考:
from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart import smtplib # 配置项 subject = "Group Email" from_addr = 'me@company.com' email_pwd = '你的公司邮箱密码' # 域账号一般直接用域登录密码即可 smtp_server = '你的公司SMTP服务器地址' smtp_port = 587 # 这里填拿到的真实通讯组地址,不要带!前缀 recipients = ['groupdept@company.com'] msg = MIMEMultipart() msg['Subject'] = subject msg['From'] = from_addr msg['To'] = ','.join(recipients) # 邮件头里的收件人字段需要拼接为字符串 html = """\ <html> <head> </head> <body style="font-size:18px;"> {0} </body> </html> """.format(df2.style .set_properties(**{'border': '2.5pt solid green', 'color': 'magenta', 'font-size': '15pt'}) .hide_index() .hide_columns() .render() ) message = MIMEText(html, 'html') msg.attach(message) # 带认证的SMTP连接 try: server = smtplib.SMTP(smtp_server, smtp_port) server.starttls() # 开启加密传输 server.login(from_addr, email_pwd) server.sendmail(from_addr, recipients, msg.as_string()) server.quit() print("发送成功") except Exception as e: print(f"发送失败: {str(e)}")
方案3:走Exchange原生协议发送
如果你们公司的通讯组没开放SMTP投递权限,就不要用smtplib了,换两种原生支持Exchange的方式:
- 如果你跑代码的机器装了桌面版Outlook客户端,直接用
pywin32库调用本地Outlook的COM接口发信,这种方式和手动在Outlook里发信逻辑完全一致,可以直接识别!开头的通讯组别名。 - 如果是无界面的服务器场景,用
exchangelib库直连公司Exchange EWS接口,用域账号认证后发信,同样支持直接解析Exchange通讯组。
内容的提问来源于stack exchange,提问作者thentangler
相关产品推荐
相关产品推荐

