使用smtplib发送Base64编码图片时内容不一致的原因及解决方法
问题原因与解决方法
为什么编码结果和邮件里的内容不一致?
咱们先揪出问题根源:
- 你用
base64.encodestring(image)得到的是一个bytes类型的对象,比如b'iVBORw0KGgo...\n'。当你直接用str(encode_image)把它转成字符串时,Python会把这个bytes对象的「字面表示」转成字符串——也就是会保留开头的b'、结尾的',还有换行符的转义\n,最终得到的字符串是"b'iVBORw0KGgo...\\n'"。 - 当你把这个带多余符号的字符串塞进邮件内容里,收到的自然就和本地原始的Base64编码结果不一样了,多了那些不必要的标识。
另外还有个小细节:base64.encodestring其实是个已经被废弃的方法,官方推荐用base64.b64encode来替代它。
如何让两者一致?
咱们分两步修改代码:
1. 修正Base64编码函数
把resim_ac函数改成这样,确保返回纯净的Base64字符串:
def resim_ac(self): dosya_ismi = QFileDialog.getOpenFileName(self, "Resim Aç", os.getenv("HOME")) # 先判断用户是否选择了文件,避免空路径报错 if not dosya_ismi[0]: return "" with open(dosya_ismi[0], "rb") as file: image = file.read() # 用b64encode替代废弃的encodestring,然后解码成utf-8字符串 encode_image = base64.b64encode(image).decode('utf-8') return encode_image if encode_image else ""
这里做了两个关键修改:
- 替换
encodestring为b64encode,符合官方规范 - 用
.decode('utf-8')把bytes对象转换成真正的Base64文本,去掉b''包裹
2. 修正邮件发送的调用
原来的代码里你写的是str(self.resim_ac),现在resim_ac已经直接返回字符串了,所以直接调用就行:
mesaj = MIMEMultipart() # 直接传入self.resim_ac()的返回值,不需要再转str mesaj_govdesi2 = MIMEText(self.resim_ac(), "plain") mesaj.attach(mesaj_govdesi2) mesaj["Subject"] = self.subject_text.text() mail = smtplib.SMTP("smtp.gmail.com", 587) mail.ehlo() mail.starttls() mail.login(self.email, self.passw) mail.sendmail(self.email, self.email_to, mesaj.as_string()) print("Mail Sended....") mail.close()
这样修改后,邮件里收到的Base64内容就会和本地编码的结果完全一致啦。
内容的提问来源于stack exchange,提问作者Twister Joe
相关产品推荐
相关产品推荐

