python-读取指定文件夹下邮件的正文(html格式)

问题描述

已知邮箱地址和密码,我需要用脚本读取某文件夹下8000多封邮件的正文,提取其中所需的内容。在测试中,我分别使用了imapclient包和imaplib包,只能说各有不便之处。不过,最终我使用的是imaplib包,完美解决我的问题。

imaplib包

注释写的很清楚了,不再解释。两个问题:

  1. 有的邮件在解码为中文时报错,最终只能以byte格式打印,那提取内容需要小心点。但是这个比例不高,我在8k+中只有3个是这样的;
  2. 比较慢。8k+封邮件用了近22分钟才保存完毕。
# -*- coding: utf-8 -*-
import imaplib, email, os

# 我用的是腾讯企业邮
imapserver = 'smtp.exmail.qq.com'
emailuser = 你的邮箱地址
emailpasswd = 你的密码
#attachementdir = r"f:\a"  # 附件存放的位置

conn = imaplib.IMAP4_SSL(imapserver)
conn.login(emailuser, emailpasswd)
conn.list()  # 列出邮箱中所有的列表.inbox是默认的收件箱,junk是垃圾箱,以此类推
# 但是!中文的文件夹名称会变成字母乱码,注意分辨
conn.select(你指定的文件夹) 
result, dataid = conn.uid('search', None, "ALL")
mailidlist = dataid[0].split()  # 转成标准列表,获得所有邮件的ID

# 解析邮件内容
def get_body(msg):
    if msg.is_multipart():
        return get_body(msg.get_payload(0))
    else:
        return msg.get_payload(None, decode=True)

# search('FROM','[email protected]',conn)  根据输入的条件查找特定的邮件
def search(key, value, conn):
    result, data = conn.search(None, key, '"()"'.format(value))
    return data

# 获取附件。我只读正文,所以没用它
def get_attachements(msg):
    for part in msg.walk():
        if part.get_content_maintype() == 'multipart':
            continue
        if part.get('Content-Disposition') is None:
            continue
        filename = part.get_filename()
        if bool(filename):
            filepath = os.path.join(attachementdir, filename)
            with open(filepath, 'wb') as f:
                f.write(part.get_payload(decode=True))

for id in mailidlist:
    result, data = conn.fetch(id, '(RFC822)')  # 通过邮件id获取邮件
    try:
        e = email.message_from_bytes(data[0][1])
        subject = email.header.make_header(email.header.decode_header(e['SUBJECT']))
        mail_from = email.header.make_header(email.header.decode_header(e['From']))
        print('-' * 10 + 'mail content' + '-' * 10)
        print("邮件的subject是%s" % subject)
        print("邮件的发件人是%s" % mail_from)
        try:
            body = get_body(e).decode('gbk') # 邮件正文有中文
            print("邮件内容是%s" % body)
        except UnicodeDecodeError: # 有些解析错误我就随缘了...
            print(get_body(e))
        print('-' * 10 + 'end' + '-' * 10)
    except TypeError:
        print('-' * 10 + ' error mail content' + '-' * 10)
        print(data)
        print('-' * 10 + 'end' + '-' * 10)

# 登出
conn.logout()

【慎用】imapclient包

这个包最大的问题是,某些格式读不到。比如网易邮箱服务器退回的邮件,形如:
python-读取指定文件夹下邮件的正文(html格式)_第1张图片
我也不知道是什么毛病,反正网易相关的有几千封我读取不到,非常恼火。

优点就是速度相对快一点,而且列出文件夹时,中文文件夹名称可以正确显示。

这里仍然放上代码,以备后续使用。

import email
import imapclient

def getAddress():
    conn = imapclient.IMAPClient(host='smtp.exmail.qq.com', ssl='True')
    print('连接成功')
    conn.login(你的用户名, 你的密码)
    conn.select_folder(你指定的文件夹, readonly=True)
    messages = conn.search() # 获取id
    msgdict = conn.fetch(messages, 'RFC822')
    file = open('maillog.txt', 'w')
    for key,val in msgdict.items():
        print("start...")
        e = email.message_from_bytes(val[b"RFC822"])
        subject = str(email.header.make_header(email.header.decode_header(e['SUBJECT'])))
        mail_from = str(email.header.make_header(email.header.decode_header(e['From'])))
        maintype = e.get_content_maintype()
        # 获取内容
        if maintype == 'multipart':
            for part in e.get_payload():
                if part.get_content_maintype() == 'text':
                    mail_content = part.get_payload(decode=True).strip()
        elif maintype == 'text':
            mail_content = e.get_payload(decode=True).strip()
        file.write('-' * 10 + 'mail content' + '-' * 10)
        # 此时,需要把content转化成中文,利用如下方法:
        try:
            mail_content = mail_content.decode('gbk')
        except UnicodeDecodeError:
            print('decode error')
            exit(1)
        except AttributeError:
            file.write(mail_content)
        else:
            file.write(mail_content.replace('
'
, '\n')) file.write('-' * 10 + 'end' + '-' * 10) file.write("\n\n\n") file.close() conn.logout()

你可能感兴趣的:(python大法好,python)