3

我正在将 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? 
  #

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

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

或者也许我不应该使用mailbox+imaplib的方式?

4

2 回答 2

5

我希望它会有用:

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"

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

于 2017-04-23T22:51:04.477 回答
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 是一个巨大的痛苦,因为您必须遍历所有消息。我想这会很糟糕。如果可能的话,最好将此类信息存储在其他地方。

祝你好运!

于 2015-04-12T20:58:14.660 回答