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

Python pandas筛选VIP联系人发送Gmail时变量调用异常问题

问题根因

你的代码存在4个核心错误,直接导致匹配关系错乱、附件异常:

  • 遍历逻辑错误:仅循环遍历df2.Email列,没有同步读取对应行的姓名字段,循环结束后content["to"]只会保留最后一个VIP的邮箱,不会逐个给VIP发件;你打印的i实际是邮箱值,根本没有关联到Name列。
  • MIMEText参数传错:MIMEText的第二个参数是正文类型(纯文本传plain,HTML传html),你把"Demo python send email"传到了类型参数位,会被邮件客户端识别为无效附件,正文也无法正常展示。
  • 缩进语法错误:原代码里try/except块、print语句缩进不符合Python语法要求,运行会直接报错。
  • 邮件对象复用错误:在循环外只初始化了一次邮件对象,多次发件时会叠加之前的收件人、正文内容,导致收件人泄露、内容错乱。
修正后代码
import pandas as pd
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib

# 读取并筛选数据
df = pd.read_excel('s1.xlsx')
print('RAW_DATA')
print(df)
print('========================================')
df1 = df.loc[df.VIP.str.startswith('Y', na=False)]  # 增加na=False避免空值报错
df0 = df.loc[df.VIP.str.startswith('N', na=False)]
df2 = pd.DataFrame(df1,columns=['Name','VIP','Email'])
df00 = pd.DataFrame(df0, columns=['Name','VIP','Email'])
print('VIP LIST')
print(df2)
print('========================================')
print('Non-VIP LIST')
print(df00)
print('========================================')

# 配置发件人信息
sender_addr = "*****@gmail.com"  # 替换为你的发件邮箱
sender_pwd = "******"  # 替换为Gmail应用专用密码

# 建立SMTP连接(整个发件流程只需要连接登录一次)
with smtplib.SMTP(host="smtp.gmail.com", port=587) as smtp:
    smtp.ehlo()
    smtp.starttls()
    smtp.login(sender_addr, sender_pwd)
    
    # 逐行遍历VIP列表,保证姓名和邮箱一一匹配
    for _, row in df2.iterrows():
        name = row['Name']
        receiver_addr = row['Email']
        
        # 每个收件人单独初始化邮件对象,避免内容残留
        content = MIMEMultipart()
        content["subject"] = "Learn Code With Mike"
        content["from"] = sender_addr
        content["to"] = receiver_addr
        
        # 构造定制化正文,修正MIMEText参数
        mail_body = f"您好 {name}:\n这是给您发送的VIP专属邮件。"
        content.attach(MIMEText(mail_body, "plain", "utf-8"))
        
        # 发送邮件
        try:
            smtp.send_message(content)
            print(f"已成功给{name}({receiver_addr})发送邮件")
        except Exception as s:
            print(f"给{name}发件失败,错误信息: ", s)

print("所有VIP邮件发送流程执行完毕")
关键修改说明
  • 用df2.iterrows()逐行遍历VIP数据,每一行同时提取姓名、邮箱字段,从根源上保证两个字段的匹配关系不会错位。
  • 每封邮件单独初始化MIMEMultipart对象,不会出现上一封邮件的收件人、正文残留到下一封的问题。
  • 修正MIMEText传参顺序:第一个参数传入拼接了联系人姓名的正文,第二个参数传plain标识纯文本格式,第三个参数指定utf-8编码避免乱码,彻底解决异常无名称附件的问题。
  • 优化SMTP连接逻辑:整个发件流程只建立一次连接、登录一次,在连接上下文内循环发件,减少不必要的网络开销,同时修正了原代码的缩进语法错误。
  • 给str.startswith()增加na=False参数,避免Excel里VIP字段为空时运行报错。

注意:Gmail现在已经不支持普通密码登录SMTP服务,需要先在谷歌账号里开启两步验证,再生成16位应用专用密码填到sender_pwd位置才能正常发件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 23:06:28