Python发送邮件问题求助:主脚本可正常运行的Outlook邮件代码
Python发送Outlook邮件问题排查指南
Hey,我看了你提供的Outlook邮件发送代码片段,结合日常排查这类问题的经验,给你梳理下可能的问题点和解决方案:
一、你的代码缺失的核心部分
你提供的代码只写到了定义邮件主头部的注释,而发送带附件的Outlook邮件需要完整的MIME邮件结构和SMTP服务器配置,这两部分是关键缺失项:
1. 完整构建MIME多部分邮件
发送带附件的邮件不能只用纯文本,必须用email.mime模块构建包含正文和附件的多部分邮件,补充示例如下:
from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase from email import encoders # 创建多部分邮件对象 msg = MIMEMultipart() msg['From'] = sender msg['To'] = reciever msg['Subject'] = "Test Email with Attachment" # 添加邮件正文 msg.attach(MIMEText(body, 'plain')) # 处理附件 part = MIMEBase('application', 'octet-stream') part.set_payload(filecontent) encoders.encode_base64(part) # 设置附件的文件名,避免路径问题 part.add_header('Content-Disposition', f'attachment; filename="{filename.split("/")[-1]}"') msg.attach(part)
2. Outlook SMTP服务器的正确配置
Outlook的SMTP服务器是smtp.office365.com,端口587,必须启用TLS加密,同时需要账号验证(注意现代Outlook账号可能需要应用密码),补充连接代码:
try: server = smtplib.SMTP('smtp.office365.com', 587) server.starttls() # 启用TLS加密,这一步不能少 # 如果你的账号开启了两步验证,这里需要用「应用密码」而非原账号密码 server.login(sender, 'your_password_or_app_password') text = msg.as_string() server.sendmail(sender, reciever, text) server.quit() print("邮件发送成功") except Exception as e: print(f"发送失败: {str(e)}")
二、常见问题排查点
结合代码和Outlook的特性,这些是最容易踩坑的地方:
- 文件权限与存在性:确保
/tmp/test.txt文件存在且当前用户有读取权限,可以提前加判断:import os if not os.path.exists(filename): print(f"错误:文件 {filename} 不存在") exit() - Base64编码的正确用法:你代码里的
encodedcontent变量没有被实际使用,正确的附件编码应该用encoders.encode_base64(如上面的示例),手动编码后直接拼接会导致邮件解析异常。 - Outlook账号权限问题:如果是Outlook.com或Office 365账号,开启两步验证后必须使用应用密码登录SMTP;未开启两步验证的账号,可能需要在账号设置里允许"不安全应用访问"(不推荐,优先用应用密码)。
- SMTP连接拦截:检查网络是否能访问
smtp.office365.com的587端口,公司网络的防火墙或代理可能会拦截这个端口。 - 收件人格式:如果发送给多个收件人,
reciever需要是列表格式(如['a@xxx.com', 'b@xxx.com']),单个收件人用字符串没问题。
三、完整可运行的示例代码
把所有部分整合起来,完整的可运行代码如下:
import smtplib import os from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase from email import encoders filename = "/tmp/test.txt" # 先检查文件是否存在且可读取 if not os.path.isfile(filename): print(f"错误:文件 {filename} 不存在或无法访问") exit(1) # 读取文件内容(用with语句更安全,自动关闭文件) with open(filename, "rb") as fo: filecontent = fo.read() sender = 'your_outlook_account@outlook.com' reciever = 'amrood.admin@gmail.com' body =""" This is a test email to send an attachment. """ # 构建MIME邮件 msg = MIMEMultipart() msg['From'] = sender msg['To'] = reciever msg['Subject'] = "Test Email with Attachment" # 添加正文 msg.attach(MIMEText(body, 'plain')) # 添加附件 part = MIMEBase('application', 'octet-stream') part.set_payload(filecontent) encoders.encode_base64(part) part.add_header('Content-Disposition', f'attachment; filename="{os.path.basename(filename)}"') msg.attach(part) # 发送邮件并捕获常见错误 try: server = smtplib.SMTP('smtp.office365.com', 587) server.starttls() # 注意:两步验证账号请替换为应用密码 server.login(sender, 'your_app_password_or_account_password') server.sendmail(sender, reciever, msg.as_string()) server.quit() print("邮件发送成功!") except smtplib.SMTPAuthenticationError: print("认证失败:请检查账号密码,或为两步验证账号生成应用密码") except smtplib.SMTPConnectError: print("连接失败:无法连接到Outlook SMTP服务器,请检查网络和端口") except Exception as e: print(f"发送出错:{str(e)}")
内容的提问来源于stack exchange,提问作者sayhiravi




