Python邮件在Outlook主题行中添加了未计算的空格

5 投票
2 回答
1702 浏览
提问于 2025-04-19 21:07

我写了一个简单的Python脚本,使用了MIMEMultipart和SMTPLib来给一组收件人发送邮件。代码大概是这样的:

import smtplib
import sys

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

sender='foo@bar.com'
recipients='someguy@bar.com'
subject='A pretty long subject line which looks like this'
mail_server='microsfot_exchange_server_ip'
msg = MIMEMultipart('alternative')
body='Body of the Email'
msg['Subject'] = subject
msg['from'] = sender
msg['to'] = ", ".join(recipients)
s = smtplib.SMTP(mail_server)
s.sendmail(sender, recipients, msg.as_string())
s.quit()

这个代码可以成功发送邮件,但在像Outlook这样的邮件客户端中,邮件的主题看起来是这样的:

 A pretty long subject line which looks       like this

2 个回答

2

你的邮件主题行超过了78个字符,因此被 .as_string() 分成了几部分。前面的一些字符在主题行上,剩下的字符则在一个或多个续行上。

当Outlook试图把原来的主题行重新组合时,它的做法是不正确的。

你可以通过避免续行来解决这个问题,像这样:

from StringIO import StringIO
from email.generator import Generator
def my_as_string(msg):
  fp = StringIO()
  g = Generator(fp, mangle_from_=False, maxheaderlen=0)
  g.flatten(msg)
  return fp.getvalue()

...

s.sendmail(sender, recipients, my_as_string(msg))

参考资料:

6

看起来你遇到了问题 #1974

长邮件头应该要换行,这个过程叫做“头部折叠”,在RFC822中有描述。不过,RFC822对头部折叠的具体操作似乎有点模糊。

2.7 / 3.1之前的Python版本中,处理方式导致了你提到的某些邮件客户端的问题(使用制表符\t作为续行符)。

在这个bug报告中,有人建议了一个解决方法:把你的主题行做成一个头部对象,像这样:

from email.header import Header

# ...

msg['Subject'] = Header(subject)

我刚刚验证过,这确实使用空格而不是制表符作为续行符,这样应该能解决你的问题。

撰写回答