从Excel读取收件人邮箱发送邮件:代码执行成功但邮件未发出
邮件发送失败问题排查与修复方案
1. 核心问题分析
你的代码能执行但无邮件发送,主要是以下几个关键问题导致:
- 缺失
send_email核心实现:代码仅调用了发送邮件的函数,但完全没有编写SMTP连接、邮件构造(含附件)、发送的核心逻辑,相当于“只喊了发送命令,但没写怎么发”。 - 缩进与逻辑混乱:
for循环和if __name__ == "__main__"的缩进错误,导致循环逻辑根本没有被正确触发;user变量仅在if __name__块内定义,循环调用send_email时可能无法读取到正确值。 - Excel初始化缺失:直接使用
sheet对象但没有加载Excel文件的代码(比如打开工作簿、指定工作表),如果sheet未正确初始化,循环不会执行,自然不会发送任何邮件。
2. 修复后的完整可运行代码
以下是包含完整邮件发送逻辑、Excel读取、正确缩进的代码示例(以Gmail SMTP为例,本地SMTP可自行调整):
#!/usr/bin/env python # -*- coding: utf-8 -*- import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase from email import encoders import openpyxl def send_email(user, password, from_addr, recipients_addr, subject, body, file_path=None): # 构造邮件主体 msg = MIMEMultipart() msg['From'] = from_addr msg['To'] = recipients_addr msg['Subject'] = subject # 添加邮件正文 msg.attach(MIMEText(body, 'plain', 'utf-8')) # 添加附件(如果有) if file_path: try: with open(file_path, "rb") as attachment: part = MIMEBase('application', 'octet-stream') part.set_payload(attachment.read()) encoders.encode_base64(part) part.add_header('Content-Disposition', f"attachment; filename= {file_path.split('/')[-1]}") msg.attach(part) except Exception as e: print(f"附件 {file_path} 添加失败: {str(e)}") return # 发送邮件 try: # Gmail SMTP配置,本地SMTP替换为smtplib.SMTP('localhost') server = smtplib.SMTP('smtp.gmail.com', 587) server.starttls() server.login(user, password) text = msg.as_string() # 支持多个收件人,按逗号分割转列表 server.sendmail(from_addr, [addr.strip() for addr in recipients_addr.split(',')], text) server.quit() print(f"邮件已发送至: {recipients_addr}") except Exception as e: print(f"发送邮件至 {recipients_addr} 失败: {str(e)}") if __name__ == "__main__": # 邮箱配置 user = 'xyz@gmail.com' password = 'secret' from_addr = 'abc@gmail.com' # 加载Excel文件,替换为你的文件路径 wb = openpyxl.load_workbook('mail_list.xlsx') sheet = wb.active # 或指定工作表名,比如wb['Sheet1'] # 遍历Excel行(从第2行开始,跳过表头) for row in sheet.iter_rows(min_row=2, values_only=True): if not row[3]: # 收件人邮箱为空则跳过 continue company = row[0] stmt = row[1] areawise = row[2] email_addresses = row[3] send_email(user, password, from_addr, email_addresses, company, stmt, areawise)
3. 额外验证点
- Gmail权限:如果使用Gmail,当前“低安全性应用”选项已被移除,建议开启2步验证后使用应用专用密码登录。
- 本地SMTP:使用postfix/sendmail时,确保服务已启动,发送函数中替换为
smtplib.SMTP('localhost'),无需登录(除非本地SMTP要求认证)。 - 收件人格式:确保Excel中收件人邮箱是逗号分隔的字符串(如
"a@test.com,b@test.com"),避免格式错误导致发送失败。 - 错误日志:添加
try-except块捕获并打印错误,能快速定位连接失败、附件不存在等问题。
内容的提问来源于stack exchange,提问作者amkSharath
相关产品推荐
相关产品推荐

