0

我设置了一个筛子过滤器,当它检测到有关包裹递送的邮政服务电子邮件时,它会调用 Python 脚本。筛子过滤器工作正常并可靠地调用 Python 脚本。但是,Python 脚本不能可靠地完成它的工作。这是我的 Python 脚本,简化为相关部分:

#!/usr/bin/env python3

import sys
from email import message_from_file
from email import policy
import subprocess

msg = message_from_file(sys.stdin, policy=policy.default)
if " out for delivery " in str(msg.get_body(("html"))):
    print("It is out for delivery")

我收到邮件" out for delivery "正文中包含字符串但脚本没有打印出来的电子邮件"It is out for delivery"。我已经检查了消息中的 HTML 以确保它是一致的并且是 100% 一致的。但令人沮丧的是,如果我从我的邮件阅读器中保存应该触发脚本的消息sieve-test,然后手动输入,那么脚本 100% 的时间都有效!

为什么我的脚本在实际邮件传递过程中从不工作,但在我测试它时总是工作sieve-test

笔记:

  1. 电子邮件仅包含一个部分,即 HTML,因此我必须使用 HTML 部分。

  2. 我知道我可以用筛子做身体测试。出于此问题范围之外的原因,我在 Python 中这样做。

4

1 回答 1

1

问题是您使用str(msg.get_body(("html"))),这对于您的目的不可靠。您得到的是作为字符串的消息正文,但它被编码以包含在电子邮件消息中。您正在处理可能用 编码的 MIME 部分,quoted-printable在这种情况下,您为 ( ) 测试的字符串" out for delivery "在编码时可能会分成多行。您测试的字符串可能具有您要查找的文本,编码如下:

[other text] out for=
delivery [more text]

=符号是编码的一部分,表示后面的换行符是因为编码而不是因为它在编码之前就在那里。

好的,但是为什么在您使用时它总是sieve-test有效?发生的情况是您的邮件阅读器对消息进行了不同的编码,并且它的编码方式,您要查找的文本没有跨行分割,并且您的脚本有效!邮件阅读器使用不同的编码保存邮件是完全正确的,只要邮件被解码后其内容没有改变。

你应该做的是使用msg.get_body(("html")).get_content(). 这使得解码形式的正文与邮政服务撰写电子邮件时的逐字节完全相同。

于 2020-01-12T14:30:18.677 回答