如何在python中使用imaplib获取电子邮件正文? [英] How to fetch an email body using imaplib in python?

查看:42
本文介绍了如何在python中使用imaplib获取电子邮件正文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从 IMAP4 服务器获取整个消息.在 python 文档中,如果发现这段代码有效:

<预><代码>>>>t, data = M.fetch('1', '(RFC822)')>>>正文 = 数据[0][1]

我想知道我是否可以始终相信 data[0][1] 返回消息的正文.当我运行 'RFC822.SIZE' 时,我只有一个字符串而不是一个元组.

我浏览了 rfc1730,但无法找出RFC822"的正确响应结构.也很难从 imaplib 文档中分辨出获取结果的结构.

这是我在获取 RFC822 时得到的:

('OK', [('1 (RFC822 {858569}', '消息正文', ')')])

但是当我获取 RFC822.SIZE 我得到:

('OK', ['1 (RFC822.SIZE 847403)'])

我应该如何正确处理 data[0] 列表?我能相信当它是一个元组列表时,元组正好有 3 部分,第二部分是有效载荷吗?

也许您知道 imap4 的任何更好的库?

解决方案

不... imaplib 是一个很不错的库,就是 imap 太难懂了.

您可能希望检查 t == 'OK',但是 data[0][1] 在我使用它的情况下按预期工作.

这是我用来提取我通过电子邮件收到的签名证书的一个简单示例,不是防弹的,但适合我的目的:

import getpass, os, imaplib, email从 OpenSSL.crypto 导入 load_certificate, FILETYPE_PEMdef getMsgs(servername="myimapserverfqdn"):usernm = getpass.getuser()passwd = getpass.getpass()主题 = '您的 SSL 证书'conn = imaplib.IMAP4_SSL(服务器名)conn.login(usernm,passwd)conn.select('收件箱')typ, data = conn.search(None,'(UNSEEN SUBJECT "%s")' % subject)对于数据 [0].split() 中的 num:typ, data = conn.fetch(num,'(RFC822)')msg = email.message_from_string(数据[0][1])typ, data = conn.store(num,'-FLAGS','\\Seen')产量信息def getAttachment(msg,check):对于 msg.walk() 的一部分:如果 part.get_content_type() == 'application/octet-stream':如果检查(part.get_filename()):返回 part.get_payload(decode=1)如果 __name__ == '__main__':对于 getMsgs() 中的 msg:有效载荷 = getAttachment(msg,lambda x: x.endswith('.pem'))如果不是有效载荷:继续尝试:cert = load_certificate(FILETYPE_PEM,payload)除了:证书 = 无如果证书:cn = cert.get_subject().commonName文件名 = "%s.pem" % cn如果不是 os.path.exists(filename):打开(文件名,'w').写(有效载荷)打印写入 %s"% 文件名别的:打印%s 已经存在"% 文件名

I'd like to fetch the whole message from IMAP4 server. In python docs if found this bit of code that works:

>>> t, data = M.fetch('1', '(RFC822)')
>>> body = data[0][1]

I'm wondering if I can always trust that data[0][1] returns the body of the message. When I've run 'RFC822.SIZE' I've got just a string instead of a tuple.

I've skimmed through rfc1730 but I wasn't able to figure out the proper response structure for the 'RFC822'. It is also hard to tell the fetch result structure from imaplib documentation.

Here is what I'm getting when fetching RFC822:

('OK', [('1 (RFC822 {858569}', 'body of the message', ')')])

But when I fetch RFC822.SIZE I'm getting:

('OK', ['1 (RFC822.SIZE 847403)'])

How should I properly handle the data[0] list? Can I trust that when it is a list of tuples the tuples has exactly 3 parts and the second part is the payload?

Maybe you know any better library for imap4?

解决方案

No... imaplib is a pretty good library, it's imap that's so unintelligible.

You may wish to check that t == 'OK', but data[0][1] works as expected for as much as I've used it.

Here's a quick example I use to extract signed certificates I've received by email, not bomb-proof, but suits my purposes:

import getpass, os, imaplib, email
from OpenSSL.crypto import load_certificate, FILETYPE_PEM

def getMsgs(servername="myimapserverfqdn"):
  usernm = getpass.getuser()
  passwd = getpass.getpass()
  subject = 'Your SSL Certificate'
  conn = imaplib.IMAP4_SSL(servername)
  conn.login(usernm,passwd)
  conn.select('Inbox')
  typ, data = conn.search(None,'(UNSEEN SUBJECT "%s")' % subject)
  for num in data[0].split():
    typ, data = conn.fetch(num,'(RFC822)')
    msg = email.message_from_string(data[0][1])
    typ, data = conn.store(num,'-FLAGS','\\Seen')
    yield msg

def getAttachment(msg,check):
  for part in msg.walk():
    if part.get_content_type() == 'application/octet-stream':
      if check(part.get_filename()):
        return part.get_payload(decode=1)

if __name__ == '__main__':
  for msg in getMsgs():
    payload = getAttachment(msg,lambda x: x.endswith('.pem'))
    if not payload:
      continue
    try:
      cert = load_certificate(FILETYPE_PEM,payload)
    except:
      cert = None
    if cert:
      cn = cert.get_subject().commonName
      filename = "%s.pem" % cn
      if not os.path.exists(filename):
        open(filename,'w').write(payload)
        print "Writing to %s" % filename
      else:
        print "%s already exists" % filename

这篇关于如何在python中使用imaplib获取电子邮件正文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆