pyzmail:使用循环变量获取单个原始邮件

时间:2018-10-07 23:19:56

标签: python

首先,我应该说,我对计算机编程不是很了解,但是由于Al Sweigart的书“使无聊的东西自动化”,我发现Python相当容易用于自动化简单的任务。

我想收集电子邮件正文。我正在尝试将家庭作业转移到电子邮件以节省纸张。我认为我可以通过获取未见邮件的数量并循环浏览来实现。如果我尝试这样做,则IDLE3外壳将变得无响应,ctrl c无任何作用,我必须重新启动外壳。

问题:为什么我不能只在server.fetch()中使用循环变量?

for msgNum in unseenMessages:
    rawMessage = server.fetch([msgNum], ['BODY[]', 'FLAGS'])

似乎您需要一个实际的数字,例如57,而不是msgNum,否则将无法正常工作。

在SO上查看了各种问题和答案之后,以下对我有用。我想它一口气收集了所有电子邮件正文。

import pyzmail
import pprint
from imapclient import IMAPClient

server = IMAPClient('imap.qq.com', use_uid=True, ssl=True)
server.login('myEmail@foxmail.com', 'myIMAPpassword')
select_info = server.select_folder('Inbox')
unseenMessages = server.search(['UNSEEN'])
rawMessage = server.fetch(unseenMessages, ['BODY[]', 'FLAGS']) 
for msgNum in unseenMessages:
    message = pyzmail.PyzMessage.factory(rawMessage[msgNum][b'BODY[]'])
    text = message.text_part.get_payload().decode(message.text_part.charset)
    print('Text' + str(msgNum) + ' = ')
    print(text)

1 个答案:

答案 0 :(得分:1)

我发现此gist带有简洁的代码和page并带有许多帮助示例

imaplibpyzmail的API之间的主要区别是pyzmail是具有解析功能和所有客户端-服务器通信的多合一软件包。但是这些程序包在标准库中分为不同的程序包。基本上,它们都提供了几乎相同的功能和相同的方法。

作为此处的另一个重要说明,pyzmail看起来已经被抛弃了。

要保存要点中的有用代码,我将其复制到此处,进行了很小的修改,例如提取main函数(注意,它适用于Python 3):

#!/usr/bin/env python
#
# Very basic example of using Python 3 and IMAP to iterate over emails in a
# gmail folder/label.  This code is released into the public domain.
#
# This script is example code from this blog post:
# http://www.voidynullness.net/blog/2013/07/25/gmail-email-with-python-via-imap/
#
# This is an updated version of the original -- modified to work with Python 3.4.
#
import sys
import imaplib
import getpass
import email
import email.header
import datetime


EMAIL_ACCOUNT = "notatallawhistleblowerIswear@gmail.com"

# Use 'INBOX' to read inbox.  Note that whatever folder is specified, 
# after successfully running this script all emails in that folder 
# will be marked as read.
EMAIL_FOLDER = "Top Secret/PRISM Documents"


def process_mailbox(M):
    """
    Do something with emails messages in the folder.  
    For the sake of this example, print some headers.
    """

    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

        msg = email.message_from_bytes(data[0][1])
        hdr = email.header.make_header(email.header.decode_header(msg['Subject']))
        subject = str(hdr)
        print('Message %s: %s' % (num, subject))
        print('Raw Date:', msg['Date'])
        # Now convert to local date-time
        date_tuple = email.utils.parsedate_tz(msg['Date'])
        if date_tuple:
            local_date = datetime.datetime.fromtimestamp(
                email.utils.mktime_tz(date_tuple))
            print ("Local Date:", \
                local_date.strftime("%a, %d %b %Y %H:%M:%S"))

def main(host, login, folder):
    with imaplib.IMAP4_SSL(host) as M:
        rv, data = M.login(login, getpass.getpass())

        print(rv, data)

        rv, mailboxes = M.list()
        if rv == 'OK':
            print("Mailboxes:")
            print(mailboxes)

        rv, data = M.select(folder)
        if rv == 'OK':
            print("Processing mailbox...\n")
            process_mailbox(M)
        else:
            print("ERROR: Unable to open mailbox ", rv)


if __name__ == '__main__':
    try:
        main('imap.gmail.com', EMAIL_ACCOUNT, EMAIL_FOLDER)
    except imaplib.IMAP4.error as e:
        print('Error while processing mailbox:', e)
        sys.exit(1)