使用smtplib添加邮件附件遇问题求助
解决添加VCF附件时的AttributeError: 'file' object has no attribute 'rfind'问题
嘿,这个错误我之前折腾邮件附件的时候也碰到过!核心原因很明确:你在添加VCF附件时,传给邮件处理库的参数类型不对——rfind是字符串的方法,报错说file对象没有这个方法,说明你把打开的文件对象直接丢给了需要字符串(比如文件路径)或者文件内容的函数,导致库内部处理时出错了。
常见错误场景
比如你可能写了类似这样的错误代码:
# 错误:直接把file对象传给set_payload with open("my_contact.vcf", "rb") as vcf_file: attachment_part = MIMEBase('application', 'vcard') attachment_part.set_payload(vcf_file) # 这里传的是file对象,不是文件内容!
正确的添加VCF附件步骤
下面是完整的可运行示例,基于Python标准库的email和smtplib模块,和你之前发纯文本邮件的逻辑兼容:
import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase from email import encoders # 1. 构建多部分邮件容器(带附件必须用这个,不能用纯文本MIMEText) msg = MIMEMultipart() msg['From'] = '你的邮箱@domain.com' msg['To'] = '收件人邮箱@domain.com' msg['Subject'] = '带有VCF联系人卡片的邮件' # 2. 添加纯文本正文 email_body = '这是一封带有VCF联系人附件的测试邮件' msg.attach(MIMEText(email_body, 'plain')) # 3. 处理VCF附件 vcf_filename = "contact.vcf" with open(vcf_filename, "rb") as attachment: # 创建附件对应的MIME对象 part = MIMEBase('application', 'vcard') # 读取文件内容作为payload,而不是传file对象! part.set_payload(attachment.read()) # 4. 对附件进行Base64编码(邮件传输要求) encoders.encode_base64(part) # 设置附件的头部信息,指定文件名 part.add_header( 'Content-Disposition', f'attachment; filename="{vcf_filename}"', ) # 5. 将附件添加到邮件中 msg.attach(part) # 6. 发送邮件(和你之前发纯文本的逻辑一致) with smtplib.SMTP('smtp你的邮箱服务商.com', 587) as server: server.starttls() server.login('你的邮箱@domain.com', '你的邮箱授权码/密码') server.send_message(msg)
关键排查点
- 检查你代码中处理附件的部分:是不是直接把
open()返回的file对象传给了set_payload或者attach方法?一定要改成读取文件内容(attachment.read())或者传入文件路径字符串(如果库支持的话)。 - 如果你用的是第三方邮件库(比如yagmail、sendgrid),去确认它的
attach方法参数要求:有些库接受文件路径字符串,有些接受file对象,但需要正确配置参数。 - 确保你用的是
MIMEMultipart作为邮件容器,而不是纯文本的MIMEText——带附件的邮件必须是多部分的。
内容的提问来源于stack exchange,提问作者rustyshackleford




