批量获取多个邮箱的首封邮件

需求

  邮件功能测试验收中,有个功能点是批量给90+邮箱发送定制文件,但是由于网络限制,只能在一个电脑上接收90+邮件并汇总,为了减少手动保存的工作量,尝试用Python脚本完成

    •     a 登录邮箱
    •     b 下载邮件
    •               c 将邮件保存到对应邮箱的文件夹中
  1. 前期准备工作----创建文件夹
    1. 参考帖子如何快速批量给新建的文件夹命名-百度经验 (baidu.com)
    2. 为防止帖子过期,简单介绍一下步骤:
      1.   在电脑空白文件夹中新建一个excel空白工作表格
      2.    一行中内容为md + 文件夹名称
      3.   保存为csv,用文档打开,将文件名的后缀修改为"bat",编码选择"ANSI",然后点击"保存"选项
  2. python脚本

    

# -*- coding: utf-8 -*-
'''
1、登录邮箱
2、获取附件
3、对照字典表将附件放入对应文件夹
'''
import poplib,email,telnetlib
import datetime,time,sys,traceback
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
import schedule
import csv
def CheckMail(user_email_address,user_password):
    try:
        # 连接pop服务器。如果没有使用SSL,将POP3_SSL()改成POP3(),且监听端口改为:110即可
        email_server = poplib.POP3_SSL(host="mail-dev.cfae.cn", port=995, timeout=10)
        print("连接pop服务器-------正常,开始验证用户邮箱")
    except:
        print("连接pop服务器-------异常,退出")
        exit(1)

    try:
        # 验证用户邮箱
        email_server.user(user_email_address)
        print("用户邮箱验证-------正常,开始验证邮箱授权码")
    except:
        print("用户邮箱验证-------异常,退出")
        exit(1)

    try:
        # 验证邮箱密码是否正确,注意不是登录密码,是授权码
        email_server.pass_(user_password)
        print("邮箱授权码验证-------正常,开始接受邮箱以及附件")
    except:
        print("邮箱授权码验证-------异常,退出")
        exit(1)
        # 开始处理邮箱相关信息
    parse_email_server(email_server,user_email_address)
def parse_email_server(email_server,user_email_address):
    resp, mails, octets = email_server.list()
    num, total_size = email_server.stat()
    # mails存储了邮件编号列表,
    index = len(mails)
    # 倒序遍历邮件
    # 倒序遍历邮件,这样取到的第一封就是最新邮件
    resp, lines, octets = email_server.retr(index)
    # lines存储了邮件的原始文本的每一行,
    # 邮件的原始文本:# lines是邮件内容,列表形式使用join拼成一个byte变量
    msg_content = b'\r\n'.join(lines).decode('utf-8')
    # 解析邮件:
    msg = Parser().parsestr(msg_content)
    # 解析邮件具体内容,包括正文,标题,和附件
    parser_content(msg,0,user_email_address)
    # 别忘记退出
    email_server.quit()

def parser_content(msg,indent,user_email_address):
    emailname = user_email_address
    if indent == 0:
        # 邮件的From, To, Subject存在于根对象上:
        # 调用解析邮件头部内容的函数
        parser_email_header(msg)
    # 下载附件
    for part in msg.walk():
        file_name = part.get_filename()  # 获取附件名称类型
        #print(file_name)
        if file_name is None:
            continue
        # 说明不是文本,则作为附件处理
        filename = decode_str(file_name)  # 对附件名称进行解码
        data = part.get_payload(decode=True)  # 下载附件
        txt_dir = "D:\\UNDERWRITING_RELATIONSHIP_DICT.csv"
        dic = {}
        cusdict(txt_dir, dic)


        folder = dic.get(emailname)
        print(folder)
        att_file = open("D:/" + folder + '/'+ filename,'wb')  # 在指定目录下创建文件,注意二进制文件需要用wb模式打开
        att_file.write(data)  # 保存附件
        att_file.close()
        print("附件:" + filename+ "保存成功!路径在【" + folder + "】文件夹下。")

    if msg.is_multipart():
        # 如果邮件对象是一个MIMEMultipart,
        # get_payload()返回list,包含所有的子对象:
        parts = msg.get_payload()
        for n, part in enumerate(parts):
            # 递归打印每一个子对象:
            return parser_content(part, indent + 1,user_email_address)
    else:
        # 解析正文
        content_type = msg.get_content_type()
        if content_type == 'text/plain' or content_type == 'text/html':
            # 纯文本或HTML内容:
            content = msg.get_payload(decode=True)
            # 要检测文本编码:
            charset = guess_charset(msg)
            if charset:
                content = content.decode(charset)
                #print('%s正文内容为: %s' % ('  ' * indent, content))

def parser_email_header(msg):
    # 解析邮件标题
    subject = msg['Subject']
    value, charset = decode_header(subject)[0]
    if charset:
        value = value.decode(charset)
    print('邮件标题: {0}'.format(value))

    # 解析发送人信息
    hdr, addr = parseaddr(msg['From'])
    # name 发送人邮箱名称, addr 发送人邮箱地址
    name, charset = decode_header(hdr)[0]
    if charset:
        name = name.decode(charset)
    print('发送人邮箱名称: {0},发送人邮箱地址: {1}'.format(name, addr))

    # 解析接收人信息
    hdr, addr = parseaddr(msg['To'])
    # name 发送人邮箱名称, addr 发送人邮箱地址
    name, charset = decode_header(hdr)[0]
    if charset:
        name = name.decode(charset)
    print('接收人邮箱名称: {0},接收人邮箱地址: {1}'.format(name, addr))
    return name


# 解码
def decode_str(s):
    value, charset = decode_header(s)[0]
    if charset:
        value = value.decode(charset)
    return value


# 猜测字符编码
def guess_charset(msg):
    # 先从msg对象获取编码:
    charset = msg.get_charset()
    if charset is None:
        # 如果获取不到,再从Content-Type字段获取:
        content_type = msg.get('Content-Type', '').lower()
        for item in content_type.split(';'):
            item = item.strip()
            if item.startswith('charset'):
                charset = item.split('=')[1]
                break
    return charset


#传入账号对应关系文件,和一个字典用来存放对应关系(创建邮箱账号与做市商名称对应关系)
def cusdict(txt_dir,dic):
    with open(txt_dir, encoding='utf-8') as f:
        for row in csv.reader(f, skipinitialspace=True):
            if row[6] not in dic:
                dic[row[6]] = row[0]

if __name__ == '__main__':
    #从文件中读取要收取的邮箱
    list = []
    with open("D:\\UNDERWRITING_RELATIONSHIP_DICT.csv", encoding='utf-8') as f:
        for row in csv.reader(f, skipinitialspace=True):
            list.append(row[6])
    print(len(list))
    for i in range (0,len(list)):
        print("收取邮箱"+list[i]+"的附件")
        CheckMail(list[i],'f3f')

 

posted @ 2022-10-16 11:10  O_din  阅读(157)  评论(0编辑  收藏  举报