使用Python邮箱模块保存IMAP消息

时间:2015-04-03 13:18:28

标签: python imap imaplib mbox

我将带有imaplib的IMAP邮件下载到mbox(带mailbox模块):

import imaplib, mailbox
svr = imaplib.IMAP4_SSL('imap.gmail.com')
svr.login('myname@gmail.com', 'mypaswword')
resp, [countstr] = svr.select("[Gmail]/All Mail", True)

mbox = mailbox.mbox('mails.mbox')

for n in range(...):
  resp, lst1 = svr.fetch(n, 'UID')    # the UID of the message
  resp, lst2 = svr.fetch(n, '(RFC822)')   # the message itself
  mbox.add(lst2[0][1])      # add the downloaded message to the mbox
  #
  # how to store the UID of this current mail inside mbox? 
  #

让我们下载UID = 1 .. 1000的邮件。下一次,我想从第1001条消息开始,而不是从第1条消息开始。但是,mailbox.mbox 不会存储UID anywhre 。所以下次我打开mbox文件时,就不可能知道我们停在哪里了。

模块mailbox是否有一种自然的方式来存储UID电子邮件?

或者我可能不会按照应有的方式使用mailbox + imaplib吗?

2 个答案:

答案 0 :(得分:1)

回答你的问题:在长时间盯着文档后,我没有看到任何干净利落的方式去做你想要的事情。如果绝对要求将UID存储在mbox文件中,那么我建议将自定义UID标题添加到您正在存储的电子邮件中:

message = email.message_from_string(lst2[0][1])
message.add_header("my_internal_uid_header", lst1[0][1])
mbox.add(message)

当然,获取最大的已保存UID是一件巨大的痛苦,因为您必须遍历所有消息。我想这会是非常糟糕。如果可能的话,最好将这些信息存储在其他地方。

祝你好运!

答案 1 :(得分:1)

我希望它会有用:

1)库和环境Win7 Anaconda3-4.3.1-Windows-x86_64.exe(新版本可用,但我使用的是

2)列出所有邮箱:

import getpass, imaplib, sys

def main():
      hostname = 'my.mail.server'
      username = 'my_user_name'
      m = imaplib.IMAP4_SSL(hostname)
      m.login(username, 'passowrd')

   try:
      print('Capabilities:', m.capabilities)
      print('Listing mailboxes ')
      status, data = m.list()
      print('Status:', repr(status))
      print('Data:')
      for datum in data:
         print(repr(datum))

   finally:
      m.logout()

if __name__ == '__main__':
   main()

3)使用生成的上述信息,我们可以将所有电子邮件从邮件服务器转储到以下目录:

import getpass, imaplib, sys, email, os , io
import codecs

BASE_NAME = 'msg_no_'
BASE_DIR = 'D:/my_email/'

def writeTofile(mailDir, partOfName, msg ):

   ## no need of dos backslash -- newDir = BASE_DIR + mailDir.replace('/', '\\')

   newDir = BASE_DIR + mailDir

   if not os.path.exists(newDir):
       os.makedirs(newDir)

   os.chdir(newDir)

   # print('Dir:' + os.getcwd() )

   file_name = BASE_NAME + partOfName  + '.eml'

   # print('Write:' + file_name)

   fw = open(newDir + '/' + file_name,'w', encoding="utf-8")
   fw.write( msg )
   fw.close()

   return


def processMailDir(m, mailDir):

   print('MailDIR:' + mailDir)

   m.select(mailbox=mailDir, readonly=True)
   typ, data = m.search(None, 'ALL')

   for num in data[0].split():
      typ, data = m.fetch(num, '(RFC822)')
      msg = email.message_from_bytes(data[0][1])

      smsg = msg.as_bytes().decode(encoding='ISO-8859-1')

      writeTofile(mailDir, num.decode(), smsg )

   m.close()

   return


def main():

   if len(sys.argv) != 3:
      hostname = 'my.mail.server'
      username = 'my_username'
      m = imaplib.IMAP4_SSL(hostname)
      m.login(username, 'password')

   else:
      hostname, username = sys.argv[1:]
      m = imaplib.IMAP4_SSL(hostname)
      m.login(username, getpass.getpass())

   try:
      print('Start...')

      processMailDir(m, 'INBOX')
      processMailDir(m, 'Sent')
      processMailDir(m, 'archive/2013/201301')
      processMailDir(m, 'archive/2013/201302')
# etc.. etc.. simple as it can be but not simpler
      print('Done...')

   finally:
      m.logout()

if __name__ == '__main__':
   main()

上面会将您的电子邮件转储到: D:\ my_email \ INBOX \ msg_no_1.eml ... msg_no203.eml

然后你需要这个秘密在Windows上打开eml:

Administrator: cmd.com:

assoc .eml=Outlook.File.eml
ftype Outlook.File.eml="C:\Program Files (x86)\Microsoft Office\Office12\OUTLOOK.EXE" /eml "%1"

亲爱的库存溢流检查员 - 请怜悯,我会发现以上有用;例如:smsg = msg.as_bytes()。decode(encoding =' ISO-8859-1')花了很长时间才弄明白。