The msg
论证smtplib.sendmail
应该是一个bytes
包含有效 RFC5322 消息的序列。获取一个字符串并将其编码为 UTF-8 不太可能产生一个字符串(如果它已经是 ASCII,则对其进行编码没有任何用处;如果不是,则很可能是您做错了)。
为了解释为什么这不太可能起作用,让我提供一些背景知识。在 MIME 消息中传输非 ASCII 字符串的方式取决于消息结构中字符串的上下文。这是一条简单的消息,其中“Hëlló”一词嵌入在三个不同的上下文中,这些上下文需要不同的编码,但没有一个可以轻松接受原始 UTF-8。
From: me <[email protected] /cdn-cgi/l/email-protection>
To: you <[email protected] /cdn-cgi/l/email-protection>
Subject: =?utf-8?Q?H=C3=ABll=C3=B3?= (RFC2047 encoding)
MIME-Version: 1.0
Content-type: multipart/mixed; boundary="fooo"
--fooo
Content-type: text/plain; charset="utf-8"
Content-transfer-encoding: quoted-printable
H=C3=ABll=C3=B3 is bare quoted-printable (RFC2045),
like what you see in the Subject header but without
the RFC2047 wrapping.
--fooo
Content-type: application/octet-stream; filename*=UTF-8''H%C3%ABll%C3%B3
This is a file whose name has been RFC2231-encoded.
--fooo--
最近有一些扩展允许符合系统之间的部分消息包含裸UTF-8(即使在标头中!),但我强烈怀疑这不是您所处的场景。也许切线也可以看到https://en.wikipedia.org/wiki/Unicode_and_email https://en.wikipedia.org/wiki/Unicode_and_email
回到你的代码,我suppose它可以工作,如果base
巧合的是,这也是您要添加到消息开头的标头的名称,并且text
包含一个带有消息其余部分的字符串。您没有显示足够的代码来智能地推理这一点,但这似乎不太可能。而如果text
已包含有效的 MIME 消息,将其编码为 UTF-8 应该没有必要或没有用(但显然没有,因为您会收到编码错误)。
我们假设base
包含Subject
and text
定义如下:
text='''=?utf-8?B?H=C3=ABll=C3=B3?= (RFC2047 encoding)
MIME-Version: 1.0
Content-type: multipart/mixed; boundary="fooo"
....'''
现在,串联base + ': ' + text
实际上会产生一条与上面类似的消息(尽管我重新排序了一些标头以放置Subject:
首先针对这个场景)但是,我想这并不是代码中实际情况。
如果您的目标是将提取的文本作为电子邮件的正文发送,则执行此操作的方法大致如下
from email.message import EmailMessage
body_text = os.path.splitext(base)[0] + ': ' + text
message = EmailMessage()
message.set_content(body_text)
message["subject"] = "Extracted text"
message["from"] = "[email protected] /cdn-cgi/l/email-protection"
message["to"] = "[email protected] /cdn-cgi/l/email-protection"
with smtplib.SMTP("smtp.gmail.com", 587) as server:
# ... smtplib setup, login, authenticate?
server.send_message(message)
此答案已更新为当前的email
库API;该行下方的文本是原始答案中较早的代码。
现代 Python 3.3+EmailMessage
API 相当直接地转化为人类概念,与旧的 API 不同,旧的 API 要求您了解消息的 MIME 结构应如何显示的许多细节。
from email.mime.text import MIMEText
body_text = os.path.splitext(base)[0] + ": " + text
sender = "[email protected] /cdn-cgi/l/email-protection"
recipient = "[email protected] /cdn-cgi/l/email-protection"
message = MIMEText(body_text)
message["subject"] = "Extracted text"
message["from"] = sender
message["to"] = recipient
server = smtplib.SMTP("smtp.gmail.com", 587)
# ... smtplib setup, login, authenticate?
server.sendmail(from, to, message.as_string())
The MIMEText()
调用构建一个电子邮件对象,其中包含发件人、主题、收件人列表和正文的空间;它是as_text()
方法返回一个看起来大致类似于ad hoc上面的示例消息(尽管更简单,没有多部分结构),适合通过 SMTP 传输。它透明地负责输入正确的字符集并为非 ASCII 标头元素和正文部分(有效负载)应用合适的内容传输编码。
Python 的标准库包含相当低级的函数,因此您必须了解相当多的知识才能正确连接所有部分。有些第三方库隐藏了一些细节;但您会期望任何电子邮件至少都有主题和正文,当然还有发件人和收件人。