一、附件里同时含文本和图片文本时,文本文件出现异常
根据 Python SMTP发送邮件 | 菜鸟教程 练习了发送HTML格式且嵌入图片的邮件,纯文本带文本附件(.txt、.docx)的邮件。
问题描述:附件查看异常
1.只有文本附件的时候,手机邮箱可以看到自定义的附件名字,并打开。
电脑网页版邮箱图片包括PDF的文件名都是自定义的,也能正常下载查看;但是文本附件显示为后缀为.bin的文件,无法查看。
2.尝试一个附件是文本,一个附件放图片时,图片文件可以正常下载打开,文本文件名字却丟了。手机点开文本会变成RAW ,无法查看;电脑下载还是后缀为.bin的文件。
期间尝试了各种代码,
甚至根据下边的链接实现了,HTML嵌入图片的同时,附上图片或PDF。
使用Python的smtplib模块发送带附件的邮件_python smtplib发送压缩包附件的邮件-CSDN博客
改进一、收信的人电脑下载文件后,手动改回原来的文件后缀,还是能看的。
于是,我在邮件正文后加一行文件名单,让收信人自己下载后改后缀。
if files is not None and len(files) != 0:
file_list = []
for fn in files:
fname = os.path.basename(fn)
file_list.append(fname)
with open(fn, "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= {fname}"
)
message.attach(part)
# 邮件正文后添加一行文件名单
message.attach(MIMEText(f"{mail_body}\n附件名:{file_list}", 'plain', 'utf-8'))
else:
message.attach(MIMEText(mail_body, 'plain', 'utf-8'))
如果是网页html,则在最后一行添加文件名的代码如下
msg_alternative.attach(MIMEText(f"{html_body}<p>\n附件名:{file_list}</p>", "html", "utf-8"))
此法麻烦, 最近重新查阅资料,找到了 解决方案。
改进二、使用 MIMEApplication 构造附件
参考文章:利用Python email的MIMEBase及MIMEApplication发送邮件附件-CSDN博客
with open(fn, "rb") as attachment:
data = attachment.read()
part = MIMEApplication(data, _subtype="octet-stream", name=fname)
我尝试了txt,docx,py,xlsx,jpg,手机和电脑都可以正常显示文件名了。
二、发送PDF格式的附件
发送PDF,将MIMEBase 第2个参数改为pdf就行了。MIMEBase 第2个参数默认是通用的 "octet-stream",像pdf这种不适配的需要更换为对应的。
att = MIMEBase("application", "pdf")
MIMEApplication 的话,可以发pdf,不用改格式 。好用!
三、发信人格式问题
如果跟我一样,找的视频和资料都比较老的,会遇到在From 赋值这行报错。原因应该是,在这些资料完成后,QQ邮箱对发送者的格式做了更严格的要求。
msg["From"] = sender
进入报错信息提供的网址,可以看到发信人现在的格式要求。发送者必须用 昵称+空格+<邮箱地址>形式 或 邮箱地址形式,才不会报错。
# 如果昵称包含非ASCII字符,如中文,则请使用base64对昵称进行编码。
# nickname最终的形式为:"=?" charset "?" encoding "?" encoded-text "?="。
# 其中,charset为字符集;encoding为编码方式,'B'代表base64;encoded-text为编码后的文本。
nickname = "来自"
encoded_nickname = Header(nickname, 'utf-8').encode()
msg["From"] = f"{encoded_nickname} <...@qq.com>"
以上代码是我尝试用含中文昵称的形式时写的,但是,完全没必要!
因为最后查看时,发送者还是我QQ邮箱默认的格式(我的是姓名+空格+<邮箱地址>)
就,完全没必要整这出,后面我都只放的邮箱(也就是登录时定义的 sender) ,能发出去就行。