You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从DataFrame多邮箱地址发送邮件仅成功首个地址的问题排查

解决多收件人邮件发送问题

你的代码核心问题在于没有正确拆分逗号分隔的邮箱地址,同时函数调用和参数传递存在错误,导致SMTP服务器实际只收到一个格式错误的收件人地址(包含逗号的单个字符串)。以下是具体修复方案:

问题点分析

  • 收件人地址未拆分:emailto = [str(row[3])] 仅将整行的邮箱字符串包装成列表,未把逗号分隔的多个邮箱拆分成独立元素,SMTP服务器会把这个带逗号的字符串当作单个收件人,自然无法投递到第二个邮箱。
  • 函数参数传递错误:循环中sendemail(df.to_html(index=False), df['email']) 传递的是整个DataFrame的email列,而非当前行的邮箱地址。
  • 函数内变量未定义:sendemail函数直接使用row变量,但该变量是循环的局部变量,函数无法正确获取,会引发逻辑错误。

修改后的完整代码

import psycopg2
import csv
import pandas
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formatdate
from datetime import date
from dateutil.relativedelta import relativedelta

try:
    conn = psycopg2.connect("dbname='' user='' host='' port='' password='' sslmode=''")
except psycopg2.Error as e:
    print ("Unable to connect to database: " + str(e))

cursor = conn.cursor()
cursor.execute(open("query.sql","r").read())

with open('file.csv', mode='w', newline='') as csv_file:
    writer = csv.writer(csv_file, delimiter=',')
    writer.writerow([ i[0] for i in cursor.description ])
    writer.writerows(cursor.fetchall())

conn.close()

df = pandas.read_csv('file.csv')

def sendemail(first_name, middle_name, last_name, exp_date, to_emails):
    emailhost = ''
    emailport = ''
    emailfrom= ''
    emailsubject = 'Subject'
    # 拆分逗号分隔的邮箱,去除空格并过滤空值
    email_list = [email.strip() for email in to_emails.split(',') if email.strip()]
    text = '''Dear {} {} {}, something happened and I want to tell you about it: {}. Thank You.'''.format(
        str(first_name), str(middle_name), str(last_name), str(exp_date)
    )
    msg = MIMEMultipart('alternative')
    part1 = MIMEText(text,'plain')
    msg['From'] = emailfrom
    msg['To'] = ', '.join(email_list)
    msg['Date'] = formatdate(localtime = True)
    msg['Subject'] = emailsubject
    msg.attach(part1)
    
    server = smtplib.SMTP(emailhost, emailport)
    # sendmail第二个参数必须是拆分后的独立邮箱列表
    server.sendmail(emailfrom, email_list, msg.as_string())
    server.quit()

for row in df.itertuples(index=False):
    # 传递当前行的具体字段给发送函数
    sendemail(row[0], row[1], row[2], row[5], row[3])

关键修改说明

  1. 拆分邮箱地址:用split(',')拆分字符串,再通过strip()去除每个邮箱前后的空格,避免因空格导致地址无效。
  2. 明确函数参数:将姓名、过期日期、邮箱等需要的字段作为参数传入函数,避免依赖外部变量,逻辑更清晰。
  3. 符合SMTP协议要求:server.sendmail()的第二个参数必须是独立邮箱地址组成的列表,而非逗号分隔的字符串,这是服务器识别多收件人的关键。
  4. 修复循环调用:循环中传递当前行的row[3](邮箱字段),而非整个DataFrame的email列。

修改后,SMTP服务器会正确识别每个收件人地址,实现向同一行的多个邮箱发送邮件。

内容的提问来源于stack exchange,提问作者vwalden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 04:45:32