Skip to main content
 首页 » 编程设计

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

2024年08月26日28zlslch

我正在使用 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 存储在任何地方。所以下次我打开 mbox 文件时,就不可能知道我们在哪里停止了。

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

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

请您参考如下方法:

希望有用:

1) 库和环境 Win7 Anaconda3-4.3.1-Windows-x86_64.exe (new is available but that I have used

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

然后你需要这个 secret 来打开 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') 花了很长时间才弄明白。