使用Python 3处理电子邮件主题行中的国际字符

时间:2016-12-21 19:57:38

标签: python python-3.x email-headers

我正在编写一个脚本来阅读未读电子邮件的主题行。我的第一次尝试:

from imaplib import IMAP4_SSL
from email.parser import HeaderParser

# username = 
# password = 
# server = 
# port = 

M = IMAP4_SSL(server, port)
M.login(username, password)
M.select()
typ, data = M.search(None, '(UNSEEN)')

for num in data[0].split():
    rv, data = M.fetch(num, '(BODY.PEEK[HEADER.FIELDS (SUBJECT FROM)])')
    header_data = data[0][1].decode('utf-8')
    parser = HeaderParser()
    msg = parser.parsestr(header_data)
    subject = msg['Subject']
    print(subject)
    print()

这适用于大多数电子邮件,但如果主题行中存在非ascii字符,则会失败。输出如下:

  

=?UTF-8 Q + This_email_has_internati = C3 = B2nal_characters?=

因此看起来HeaderParser不处理编码(在RFC 1342中指定)。查看文档,我似乎需要使用decode_headermake_header。我的第二次尝试:

# same setup code as before

from email.header import decode_header, make_header

for num in data[0].split():
    rv, data = M.fetch(num, '(BODY.PEEK[HEADER.FIELDS (SUBJECT FROM)])')
    headers_encoded = data[0][1].decode('latin-1')
    #print(headers_encoded)
    header_code_pairs = decode_header(headers_encoded)
    #print(header_code_pairs)
    headers = make_header(header_code_pairs)
    parser = HeaderParser()
    msg = parser.parsestr(str(headers))
    subject = msg['Subject']
    print(subject)
    print()

输出如下:

  

此电子邮件仅限ASCII

     

此电子邮件包含国际字符来自:Tester Testee   < ichaelmtest@gmail.com>

由于某种原因,它将From字段连接到第二个字段。但它确实正确解码了字符!这两封电子邮件的标题顺序相同。当我取消注释headers_encodedheader_code_pairs打印时,我得到了这个:

  

主题:此电子邮件仅包含ASCII:来自Tester Testee

     

[('主题:此电子邮件仅包含ASCII \ r \ nFrom:Tester Testee   < ichaelmtest@gmail.com> \ r \ n \ r \ n',无)]

     

主题:=?UTF-8?Q?This_email_has_internati = C3 = B2nal_characters?=   来自:Tester Testee

     

[(b'Subject:',None),(b这封电子邮件有内部\ xc3 \ xb2nal   characters','utf-8'),(b'From:Tester Testee   < ichaelmtest@gmail.com>',无)]

所以对我而言,这看起来问题是由于在国际示例中decode_header错过了字段之间的CRFL这一事实。因此,当make_header读取它时,它只会看到一个字段。

我可以通过在解码之前分离标题的行来解决这个问题,但是我错过了什么?还有更好的方法吗?

this old question的答案都没有解决我的示例中的问题,因此我将其作为我自己的问题发布,因为我使用make_header的代码会产生不同的错误。如果要在不使用真实邮箱的情况下重现错误,您应该能够将以下块粘贴到文本编辑器中,并将其加载而不是data[0][1]

Subject: =?UTF-8?Q?This_email_has_internati=C3=B2nal_characters?=
From: Tester Testee <ichaelmtest@gmail.com>

0 个答案:

没有答案