Python电子邮件quotedprintable编码问题

2024-04-18 07:56:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用以下方法从Gmail中提取电子邮件:

def getMsgs():
 try:
    conn = imaplib.IMAP4_SSL("imap.gmail.com", 993)
  except:
    print 'Failed to connect'
    print 'Is your internet connection working?'
    sys.exit()
  try:
    conn.login(username, password)
  except:
    print 'Failed to login'
    print 'Is the username and password correct?'
    sys.exit()

  conn.select('Inbox')
  # typ, data = conn.search(None, '(UNSEEN SUBJECT "%s")' % subject)
  typ, data = conn.search(None, '(SUBJECT "%s")' % subject)
  for num in data[0].split():
    typ, data = conn.fetch(num, '(RFC822)')
    msg = email.message_from_string(data[0][1])
    yield walkMsg(msg)

def walkMsg(msg):
  for part in msg.walk():
    if part.get_content_type() != "text/plain":
      continue
    return part.get_payload()
然而,我得到的一些电子邮件几乎不可能从编码相关字符(如‘=’)中提取日期(使用正则表达式),在各种文本字段的中间随机地出现。下面是一个示例,它发生在我要提取的日期范围内:

Name: KIRSTI Email: kirsti@blah.blah Phone #: + 999 99995192 Total in party: 4 total, 0 children Arrival/Departure: Oct 9= , 2010 - Oct 13, 2010 - Oct 13, 2010

有没有办法删除这些编码字符


Tags: toindatais电子邮件defmsgconn
3条回答

这就是所谓的引用可打印编码。您可能想要使用类似quopri.decodestring-http://docs.python.org/library/quopri.html的东西

如果您使用的是Python3.6或更高版本,则可以使用^{}方法自动解码文本。此方法取代了get_payload(),尽管get_payload()仍然可用

假设您有一个包含此电子邮件的字符串s(基于文档中的examples):

Subject: Ayons asperges pour le =?utf-8?q?d=C3=A9jeuner?=
From: =?utf-8?q?Pep=C3=A9?= Le Pew <pepe@example.com>
To: Penelope Pussycat <penelope@example.com>,
 Fabrette Pussycat <fabrette@example.com>
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0

    Salut!

    Cela ressemble =C3=A0 un excellent recipie[1] d=C3=A9jeuner.

    [1] http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718

     Pep=C3=A9
   =20

字符串中的非ascii字符已使用quoted-printable编码进行编码,如Content-Transfer-Encoding头中所指定

创建电子邮件对象:

import email
from email import policy

msg = email.message_from_string(s, policy=policy.default)

此处需要设置策略;否则使用^{},返回一个没有get_content方法的遗留消息实例^{}最终将成为默认策略,但从Python3.7开始,它仍然是policy.compat32

get_content()方法自动处理解码:

print(msg.get_content())

Salut!

Cela ressemble à un excellent recipie[1] déjeuner.

[1] http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718

 Pepé

如果您有一条多部分消息,则需要对各个部分调用get_content(),如下所示:

for part in message.iter_parts():
    print(part.get_content())

例如,您可以/应该使用^{}模块对邮件消息进行解码(快速和肮脏的示例!):

from email.parser import FeedParser
f = FeedParser()
f.feed("<insert mail message here, including all headers>")
rootMessage = f.close()

# Now you can access the message and its submessages (if it's multipart)
print rootMessage.is_multipart()

# Or check for errors
print rootMessage.defects

# If it's a multipart message, you can get the first submessage and then its payload
# (i.e. content) like so:
rootMessage.get_payload(0).get_payload(decode=True)

使用^{}的“decode”参数,模块根据其编码(例如,如您问题中引用的可打印内容)自动解码内容

相关问题 更多 >