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

Bas*_*asj 3 python imap mbox imaplib

我正在将消息从 IMAP 下载imaplib到 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? 
  #
Run Code Online (Sandbox Code Playgroud)

让我们下载 UID = 的邮件1 .. 1000。下次,我想从第 1001 条消息开始,而不是从第 1 条开始。但是,mailbox.mbox 不存储UID任何地方。所以下次我打开 mbox 文件时,将无法知道我们停在哪里。

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

或者也许我没有按应有的方式使用mailbox+ ?imaplib

小智 6

我希望它会有用:

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()
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

上面会将您的电子邮件转储到: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"
Run Code Online (Sandbox Code Playgroud)

亲爱的stockoverflow审查员 - 请仁慈,我发现上面很有用;例如: smsg = msg.as_bytes().decode(encoding='ISO-8859-1') 花了很长时间才弄清楚。