代码之家  ›  专栏  ›  技术社区  ›  Jay

多线程IMAP备份

  •  0
  • Jay  · 技术社区  · 7 年前

    我有以下python脚本,它可以将IMAP文件夹保存到本地。eml文件。我想备份我的旧电子邮件,但它有相当大的收件箱。下面的代码是否可以用多线程修改?或者是几个循环,以便在大型IMAP文件夹上更快地工作?

    非常感谢!

    import sys
    import imaplib
    import getpass
    
    IMAP_SERVER = ''
    EMAIL_ACCOUNT = ""
    EMAIL_FOLDER = "Inbox"
    OUTPUT_DIRECTORY = './'
    
    PASSWORD = getpass.getpass()
    
    
    def process_mailbox(M):
        """
        Dump all emails in the folder to files in output directory.
        """
    
        rv, data = M.search(None, "ALL")
        if rv != 'OK':
            print "No messages found!"
            return
    
        for num in data[0].split():
            rv, data = M.fetch(num, '(RFC822)')
            if rv != 'OK':
                print "ERROR getting message", num
                return
            print "Writing message ", num
    
            f = open('%s/%s.eml' %(OUTPUT_DIRECTORY, num), 'wb')
            f.write(data[0][1])
            f.close()
    
    def main():
        M = imaplib.IMAP4_SSL(IMAP_SERVER)
        M.login(EMAIL_ACCOUNT, PASSWORD)
        rv, data = M.select(EMAIL_FOLDER)
        if rv == 'OK':
            print "Processing mailbox: ", EMAIL_FOLDER
            process_mailbox(M)
            M.close()
        else:
            print "ERROR: Unable to open mailbox ", rv
        M.logout()
    
    if __name__ == "__main__":
        main()
    
    2 回复  |  直到 7 年前
        1
  •  0
  •   Max    7 年前

    您是否尝试过一次获取多条消息?Fetch能够提取多条消息: m.fetch("1:*", (RFC822)") 将获取邮箱中的所有邮件,但这是一种很好的内存不足的方法。

    如果你有很多内存,也许可以尝试批量获取100个。这可能会将其速度提高20到50倍,因为瓶颈通常是网络往返。

        2
  •  0
  •   Peter Moore    3 年前

    我使用线程池来处理这样的工作负载,工作人员的数量可以很容易地进行调整。这是给你的模板。

    def my_imap_function(lid,hid):
        .....
        
    with ThreadPoolExecutor(max_workers=3) as executor:
    
                batches[(0,99), (100,199) ... ]
                futures = [executor.submit(my_imap_function, lowid, highid) for lowid, highid in batches]
                for future in as_completed(futures):
                    if future.result() is False:
                        print('this batch failed', future.result())
    

    这里有更多信息 https://docs.python.org/3/library/concurrent.futures.html