当我使用 utf-8 编码时,为什么这个 Python 程序会发送空电子邮件? [复制]

2024-04-27

在对 msg 变量进行编码之前,我收到此错误:

UnicodeEncodeError:“ascii”编解码器无法对字符“\xfc”进行编码 位置 4:序号不在范围内(128)

所以我做了一些研究,最后对变量进行了编码:

msg = (os.path.splitext(base)[0] + ': ' + text).encode('utf-8')
server.sendmail('[email protected] /cdn-cgi/l/email-protection', '[email protected] /cdn-cgi/l/email-protection', msg)

这是根据要求的其余代码:

def remind_me(path, time, day_freq):

for filename in glob.glob(os.path.join(path, '*.docx')):
    # file_count = sum(len(files))
    # random_file = random.randint(0, file_number-1)
    doc = docx.Document(filename)
    p_number = len(doc.paragraphs)

    text = ''
    while text == '':
        rp = random.randint(0, p_number-1) # random paragraph number
        text = doc.paragraphs[rp].text # gives the entire text in the paragraph

    base = os.path.basename(filename)
    print(os.path.splitext(base)[0] + ': ' + text)
    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.starttls()
    server.login('[email protected] /cdn-cgi/l/email-protection', 'password')
    msg = (os.path.splitext(base)[0] + ': ' + text).encode('utf-8')
    server.sendmail('[email protected] /cdn-cgi/l/email-protection', '[email protected] /cdn-cgi/l/email-protection', msg)
    server.quit()

现在,它发送空电子邮件而不是传递消息。它返回 None 吗?如果是这样,为什么?

注意:Word 文档包含一些字符,如 ş、ö、ğ、ç。


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+EmailMessageAPI 相当直接地转化为人类概念,与旧的 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 的标准库包含相当低级的函数,因此您必须了解相当多的知识才能正确连接所有部分。有些第三方库隐藏了一些细节;但您会期望任何电子邮件至少都有主题和正文,当然还有发件人和收件人。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当我使用 utf-8 编码时,为什么这个 Python 程序会发送空电子邮件? [复制] 的相关文章

  • Pandas 将行中的非空值获取到一个单元格中[重复]

    这个问题在这里已经有答案了 给定以下数据框 a pd DataFrame A 1 2 B 4 0 C 1 2 a A B C 0 1 4 1 1 2 0 2 我想创建一个新专栏D包含由列分隔的非空值 每行 像这样 A B C D 0 1 4
  • ipdb 和 pdb++ 之间的区别?

    Python 有一个名为 pdb 的默认调试器 但社区创建了一些替代品 其中两个是ipdb https github com gotcha ipdb and pdb https github com pdbpp pdbpp 它们似乎迎合了相
  • 带有指针数组的 cython

    我在 python 中有一个 numpy ndarrays 列表 具有不同的长度 并且需要非常快速地访问 python 中的列表 我认为指针数组就可以解决问题 我试过 float type t list of arrays no of ar
  • 静态文件配置不正确

    我已经在 Heroku 上部署了简单的博客应用程序 它运行在Django 1 8 4 我在静态文件方面遇到了一些问题 当打开我的应用程序时 我看到Application Error页面 所以我尝试调试它并发现当我提交到 Heroku 时它无
  • 使用信号时出现 django TransactionManagementError

    我有一个与 django 的用户和 UserInfo 一对一的字段 我想订阅用户模型上的 post save 回调函数 以便我也可以保存 UserInfo receiver post save sender User def saveUse
  • 创建一个打开文件并创建字典的函数

    我有一个正在处理的文件 我想创建一个读取文件并将内容放入字典中的函数 然后该字典需要通过 main 函数传递 这是主程序 它无法改变 我所做的一切都必须与主程序配合 def main sunspot dict file str raw in
  • 通过鼻子测试检查某个函数是否发出警告

    我正在使用编写单元测试nose http somethingaboutorange com mrl projects nose 0 11 2 我想检查函数是否引发警告 该函数使用warnings warn 这是很容易就能做到的事情吗 def
  • 将 matplotlib png 转换为 base64 以在 html 模板中查看

    背景 你好 我正在尝试制作一个简单的网络应用程序 按照教程计算阻尼振动方程 并将结果的 png 返回到 html 页面 然后将其转换为 Base64 字符串 Problem 该应用程序运行正常 只是在计算结果时返回损坏的图像图标 可能是因为
  • 在 keras 中使用自定义张量流操作

    我在张量流中有一个脚本 其中包含自定义张量流操作 我想将代码移植到 keras 但我不确定如何在 keras 代码中调用自定义操作 我想在 keras 中使用tensorflow 所以到目前为止我发现的教程描述了与我想要的相反的内容 htt
  • Pandas Pivot_Table :非数字值的行计算百分比

    这是我在数据框 df 中的数据 Document Name Time SPS2315511 A 1 HOUR SPS2315512 B 1 2 HOUR SPS2315513 C 2 3 HOUR SPS2315514 C 1 HOUR S
  • 属性错误:类型对象“图像”没有属性“打开”

    Exception in Tkinter callback Traceback most recent call last File C Python34 lib tkinter init py line 1482 in call retu
  • 如何使用 python 操作系统更改驱动器?

    我正在尝试更改当前目录C to Y 我试过 import os os chdir Y 但我不断收到错误消息 提示无法找到驱动器 本质上我正在寻找相当于 cd d cmd 中的命令 你确定吗Y 确实是有效的驱动器号吗 Try os chdir
  • 提交表格并上传带有请求的文件

    我正在努力提交特定的表格蟒蛇请求 http www python requests org 我想使用它的网站上的其他表单工作正常 我可以提交登录表单等 这只是我遇到问题的文件上传 显然 提交表单效果很好 因为我从网站收到一条消息 说 请返回
  • 如何从数据框的单元格中获取值?

    我构建了一个条件 从我的数据框中提取一行 d2 df df l ext l ext df item item df wn wn df wd 1 现在我想从特定列中获取一个值 val d2 col name 但结果 我得到一个包含一行和一列
  • Python 垃圾收集有时在 Jupyter Notebook 中不起作用

    我的一些 Jupyter 笔记本经常出现 RAM 不足的情况 而且我似乎无法释放不再需要的内存 这是一个例子 import gc thing Thing result thing do something thing None gc col
  • 如何在 Python 中仅列出 zip 存档中的文件夹?

    如何仅列出 zip 存档中的文件夹 这将列出存档中的每个文件夹和文件 import zipfile file zipfile ZipFile samples sample zip r for name in file namelist pr
  • 向量化 numpy bincount

    我有一个 2d numpy 数组 A我要申请np bincount 到矩阵的每一列A生成另一个二维数组B由原始矩阵每列的 bincounts 组成A 我的问题是 np bincount 是一个采用一维数组的函数 它不是像这样的数组方法B A
  • 从 csv 中读取 pandas 数据帧,以非固定标头开始

    我有许多数据文件是由我的实验室中使用的一些相当黑客的脚本生成的 该脚本非常有趣 因为它在标头之前附加的行数因文件而异 尽管它们具有相同的格式并具有相同的标头 我正在编写一个批处理来将所有这些文件处理为数据帧 如果我不知道位置 如何让 pan
  • 从 Python 中编译的正则表达式中提取命名组正则表达式模式

    我有一个 Python 正则表达式 其中包含多个命名组 但是 如果先前的组已匹配 则可能会错过与一组匹配的模式 因为似乎不允许重叠 举个例子 import re myText sgasgAAAaoasgosaegnsBBBausgisego
  • Jupyter Notebook 中的多处理与线程

    我试图测试这个例子here https ipywidgets readthedocs io en stable examples Widget 20Asynchronous html将其从线程更改为多处理 在 jupyter Noteboo

随机推荐