Python:这种编码是什么?如何解码



我有很多来自邮件正文的字符串,打印如下:

=C3=A9

例如,这应该是"é"。

这种编码究竟是什么?如何解码?

我使用的是python 3.5

编辑:

我设法通过应用对邮件正文进行了正确编码

quopri.decodestring(sometext).decode('utf-8') 

然而,我仍然很难把"开始"、"结束"、"主题"等部分弄对。

这就是我构建电子邮件的方式:

import imaplib
import email
import quopri

mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login('mail@gmail.com', '*******')
mail.list()
mail.select('"[Gmail]/All Mail"') 

typ, data = mail.search(None, 'SUBJECT', '"{}"'.format('123456'))
data[0].split()
print(data[0].split())
for e_mail in data[0].split():
typ, data = mail.fetch('{}'.format(e_mail.decode()),'(RFC822)')
raw_mail = data[0][1]
email_message = email.message_from_bytes(raw_mail)
if email_message.is_multipart():
for part in email_message.walk():
if part.get_content_type() == 'text/plain':
if part.get_content_type() == 'text/plain':
body = part.get_payload()
to = email_message['To']
utf = quopri.decodestring(to)
text = utf.decode('utf-8')
print(text)
.
.
.

我还记得这个:=?UTF-8?BUMOpdGVyFBldMWRY3o=?=

这被称为"带引号的可打印"编码。它由RFC 1521定义。其目的是用一系列正常、安全的字符替换不寻常的字符值,以便电子邮件系统可以安全地处理邮件。

事实上,这里有两个级别的编码。首先将字母'é'编码为UTF-8,生成'xc3xa9',然后将UTF-8编码为可打印的引用形式'=C3=A9'

您可以使用quopri模块的decodedecodestring方法撤消引用的可打印步骤,如https://docs.python.org/3/library/quopri.html这看起来像:

import quopri
source = '=C3=A9'
print(quopri.decodestring(source))

这将撤消引用的可打印编码,并显示UTF-8字节'xc3xa9'。要返回字母'é',您需要使用decode字符串方法,并告诉Python这些字节包含UTF-8编码,类似于:

utf = quopri.decodestring(source)
text = utf.decode('utf-8')
print(text)

UTF-8只是将字母编码为字节的多种可能方式之一。例如,如果您的'é'被编码为ISO-8859-1,则它的字节值为'xe9',而其引用的可打印表示形式为'=E9'

当您处理电子邮件时,您应该看到Content-Type标题,该标题告诉您要发送的内容类型,以及对邮件的文本(或多部分邮件中的单个MIME部分(应用了哪种字母到字节的编码。如果随后通过应用引用的可打印编码再次对该文本进行编码,则应使用内容传输编码标头指示该附加步骤。因此,您的UTF-8编码文本以引用的可打印格式携带的消息应该有这样的标题:

Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable

这解决了它:

from email.header import decode_header
def mail_header_decoder(self,header):
if header != None:
mail_header_decoded = decode_header(header)
l=[]  
header_new=[]
for header_part in mail_header_decoded: 
l.append(header_part[1])
if all(item == None for item in l):
# print(header)
return header
else:
for header_part in mail_header_decoded:
header_new.append(header_part[0].decode())
header_new = ''.join(header_new) # convert list to string
# print(header_new)
return header_new

最新更新