在 Python 中使用 imaplib 提取多语言电子邮件数据时解码十六进制
Decoding Hex when pulling Multilingual Email Data with imaplib in Python
如何打开这个:
With Best Regards, JS Chen*\r\n\r\n=E9=A0=8E=E9=82=A6=E7=A7=91=E6=8A=80=E8=82=A1=E4=BB=BD=E6=9C=89=E9=99=90=E5=\r\n=85=AC=E5=8F=B8/Chipbond Technology
对此:
With Best Regards, JS Chen*\r\n\r\n頎邦科技股份有限公司/Chipbond Technology
使用 python?
我正在使用 imaplib 提取混合语言电子邮件数据,只要有其他语言字符,它就会给我这个带有等号的十六进制代码
这是我的代码:
mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login('****@gmail.com', '*********')
mail.select('Inbox')
type, data = mail.search(None,'(SUBJECT "ULVAC RSH-820")')
mail_ids = data[0]
id_list = mail_ids.split()
print('searching...')
for num in data[0].split():
typ, data = mail.fetch(num, '(RFC822)' )
raw_email = data[0][1]
raw_email_string = raw_email.decode('utf-8')
email_message = email.message_from_string(raw_email_string)
print('decoding..')
for response_part in data:
if isinstance(response_part, tuple):
msg = email.message_from_string(response_part[1].decode('utf-8'))
if msg.is_multipart():
print('de-partitioning...')
for part in msg.walk():
ctype = part.get_content_type()
cdispo = str(part.get('Content-Disposition'))
if ctype == 'text/plain' and 'attachment' not in cdispo:
body = part.get_payload()
else:
body = msg.get_payload()
您的电子邮件有一个 content transfer encoding, specifically, the Quoted-Printable encoding,用于确保电子邮件数据流是 ASCII 安全的。
通过将 decode=True
传递给 Message.get_payload()
method 来告诉 Python 解码有效载荷:
body_data = part.get_payload(decode=True)
charset = part.get_param("charset", "ASCII")
body = body_data.decode(charset, errors="replace")
但是,这确实意味着您将获得 二进制 数据,即使是文本内容类型,因此必须显式解码数据。 get_payload()
在这里没有多大帮助。它也是遗产的一部分API;你想切换到更新的 Unicode 友好 API。通过在加载消息时使用 compat32
策略(默认)以外的策略来执行此操作:
from email import policy
# ...
raw_email = data[0][1]
# you may have to use policy.default instead, depending on the line endings
# convention used.
email_message = email.message_from_bytes(raw_email, policy=policy.SMTP)
再往下
msg = email.message_from_bytes(response_part[1], policy=policy.SMTP)
请注意,我没有首先解码 bytes
值,通过使用 email.message_from_bytes()
而不是 email.message_from_string()
,您将解码数据委托给 email
解析器。
现在 email_message
是一个 email.message.EmailMessage
instance instead of the older email.message.Message()
type, and you can use the EmailMessage.get_content()
method,对于文本 mime 类型将 return 一个 Unicode 文本字符串:
body = part.get_content()
如何打开这个:
With Best Regards, JS Chen*\r\n\r\n=E9=A0=8E=E9=82=A6=E7=A7=91=E6=8A=80=E8=82=A1=E4=BB=BD=E6=9C=89=E9=99=90=E5=\r\n=85=AC=E5=8F=B8/Chipbond Technology
对此:
With Best Regards, JS Chen*\r\n\r\n頎邦科技股份有限公司/Chipbond Technology
使用 python?
我正在使用 imaplib 提取混合语言电子邮件数据,只要有其他语言字符,它就会给我这个带有等号的十六进制代码
这是我的代码:
mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login('****@gmail.com', '*********')
mail.select('Inbox')
type, data = mail.search(None,'(SUBJECT "ULVAC RSH-820")')
mail_ids = data[0]
id_list = mail_ids.split()
print('searching...')
for num in data[0].split():
typ, data = mail.fetch(num, '(RFC822)' )
raw_email = data[0][1]
raw_email_string = raw_email.decode('utf-8')
email_message = email.message_from_string(raw_email_string)
print('decoding..')
for response_part in data:
if isinstance(response_part, tuple):
msg = email.message_from_string(response_part[1].decode('utf-8'))
if msg.is_multipart():
print('de-partitioning...')
for part in msg.walk():
ctype = part.get_content_type()
cdispo = str(part.get('Content-Disposition'))
if ctype == 'text/plain' and 'attachment' not in cdispo:
body = part.get_payload()
else:
body = msg.get_payload()
您的电子邮件有一个 content transfer encoding, specifically, the Quoted-Printable encoding,用于确保电子邮件数据流是 ASCII 安全的。
通过将 decode=True
传递给 Message.get_payload()
method 来告诉 Python 解码有效载荷:
body_data = part.get_payload(decode=True)
charset = part.get_param("charset", "ASCII")
body = body_data.decode(charset, errors="replace")
但是,这确实意味着您将获得 二进制 数据,即使是文本内容类型,因此必须显式解码数据。 get_payload()
在这里没有多大帮助。它也是遗产的一部分API;你想切换到更新的 Unicode 友好 API。通过在加载消息时使用 compat32
策略(默认)以外的策略来执行此操作:
from email import policy
# ...
raw_email = data[0][1]
# you may have to use policy.default instead, depending on the line endings
# convention used.
email_message = email.message_from_bytes(raw_email, policy=policy.SMTP)
再往下
msg = email.message_from_bytes(response_part[1], policy=policy.SMTP)
请注意,我没有首先解码 bytes
值,通过使用 email.message_from_bytes()
而不是 email.message_from_string()
,您将解码数据委托给 email
解析器。
现在 email_message
是一个 email.message.EmailMessage
instance instead of the older email.message.Message()
type, and you can use the EmailMessage.get_content()
method,对于文本 mime 类型将 return 一个 Unicode 文本字符串:
body = part.get_content()