【问题标题】:How to distinguish sender-generated carriage returns from word wrap auto-generated carriage returns in email body?如何区分发件人生成的回车与电子邮件正文中自动换行的回车?
【发布时间】:2011-03-30 07:55:37
【问题描述】:

如何在电子邮件正文中区分发件人生成的回车和自动换行的回车?我正在使用 Python imaplib 访问 Gmail 并下载邮件正文,如下所示:

user='whoever@gmail.com'
pwd='password'
m = imaplib.IMAP4_SSL("imap.gmail.com")
m.login(user,pwd)
m.select("INBOX")
resp, items = m.search(None, "ALL")
items = items[0].split()
messages = []
for emailid in items:
    resp, data = m.fetch(emailid, "(RFC822)")
    email_body = data[0][1]
    mail = email.message_from_string(email_body)
    for part in mail.walk():
        if part.get_content_type() == 'text/plain':
            body = part.get_payload(decode=1)
            messages.append(body)

我关注的是从其他 Gmail 用户收到邮件的情况。消息正文文本中有许多回车符 ('\r\n')。这些分为两类:1) 由电子邮件发件人插入的那些,“真”返回,2) 那些由 Gmail 自动换行创建的约 78 个字符,“假”返回。我只想删除第二类回车。我确信我可以想出一个程序化的近似值,在每 78 个字符附近的窗口中搜索 '\r\n' ,但这不是防弹的,也不是我想要的。有趣的是,我注意到当邮件在网络浏览器的 Gmail 中显示时,第二类回车没有回车。 Gmail 不知何故知道要删除/不专门显示这些。如何?是否缺少一些特殊的编码?

【问题讨论】:

    标签: python email gmail


    【解决方案1】:

    Gmail 以 MIME 多部分格式发送消息,包括 text/plain 版本(您正在抓取的内容)和 text/html 版本。后一个版本包含花哨的格式,如粗体、斜体、链接等,并且是 Gmail 显示的内容。虽然 text/html 版本也是 78 个字符的换行符(电子邮件标准的一部分 - 基础文本的行不得超过 78 个字符),但您正在寻找的“真正”换行符是作为 HTML <br> 标签嵌入其中。如果您向自己发送一条消息,然后使用“回复”按钮旁边的小向下箭头,您可以自己看到这一点,然后点击“显示原件”。

    您无法区分消息的文本/纯文本版本中的“假”和“真实”换行符,至少不可靠(正如您显然知道的那样)。但是,您可以拉取 text/html 版本,然后知道“真正的”换行符是 <br> 标签,但是您必须处理额外的 HTML(以及首先正确处理其中使用的“Content-Transfer-Encoding”)。

    【讨论】:

    • 谢谢。我一直忽略文本/html,这显然是我要找的。当您提到正确处理 Content-Transfer-Encoding 时,您指的是除了在 get_payload() 中使用 decode=True 之外的任何内容吗?
    • 我真的不知道,我从来没有在 Python 中用电子邮件做过任何事情,所以不能谈这个。不过,试试吧,然后把它给你的东西倒掉——如果你看到一长行带有 HTML 中断标签的文本,那么你就明白了(或者长行偶尔会在之前所说的 HTML 中断标签的地方被打断—— - 我不知道该方法会做多少“解码”)。
    • 好的,是的,解码成功了,它打印出 HTML 流。现在来看看解析 HTML 的乐趣。 ;)
    【解决方案2】:

    我不知道有多少电子邮件客户端正确解释或生成此内容,但RFC 3676 包括以下内容:

    在创建流式文本时,生成代理会换行,即 根据需要插入“软”换行符。软换行符添加在 自然的包裹点,例如单词之间。软换行符是 一个 SP CRLF 序列。

    所以如果前一行的末尾有一个空格,那么当前行应该被解释为前一行的延续。我建议查看整个 RFC。

    【讨论】:

    • 谢谢。问题是行尾的空格被替换为 '\r\n',如下所示:'它比我们正在寻找的要小一些,所以我们很快就会处理一个主\r\n套件添加搬进来后。'
    猜你喜欢
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多