python接收未读邮件并将满足主题为XX的邮件正文存放到表格中

刚开始用的poplib库,后来发现imbox库中可以直接获取未读邮件,又改用了imbox,下面两种方法都有,自己辨别使用;

读取表格内容,也分别写了xlwt.xlrd,两种也有区别

 

 

# -*- coding: utf-8 -*-
# @Time    : 2020/05/28 16:37
# @File    : zking_receive_mail.py
# ==================================
import csv
import codecs
import poplib
import xlwt
import xlrd

from imbox import Imbox
import keyring
import sys,os
# 解析邮件
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
from openpyxl import load_workbook
print ("sys.argv[0]------"+sys.argv[0])


def cur_file_dir():
    # 获取脚本路径
    path = sys.path[0]
    # 判断为脚本文件还是py2exe编译后的文件,如果是脚本文件,则返回的是脚本的目录,如果是py2exe编译后的文件,则返回的是编译后的文件路径
    if os.path.isdir(path):
        return path
    elif os.path.isfile(path):
        return os.path.dirname(path)
    print ("path----"+path)


# 解析消息头中的字符串
# 没有这个函数,print出来的会使乱码的头部信息。如'=?gb18030?B?yrXWpL3hufsueGxz?='这种
# 通过decode,将其变为中文
def decode_str(s):
    value, charset = decode_header(s)[0]
    if charset:
        value = value.decode(charset)
    return value


# 解码邮件信息分为两个步骤,第一个是取出头部信息
# 首先取头部信息
# 主要取出['From','To','Subject']
'''
From: "=?gb18030?B?anVzdHpjYw==?="
To: "=?gb18030?B?ztLX1Ly6tcTTys/k?="
Subject: =?gb18030?B?dGV4dMTjusM=?=
'''


# 如上述样式,均需要解码
def get_header(msg):
    info = []
    for header in ['From', 'To', 'Subject']:
        value = msg.get(header, '')
        if value:
            # 文章的标题有专门的处理方法
            if header == 'Subject':
                value = decode_str(value)
            elif header in ['From', 'To']:
                # 地址也有专门的处理方法
                hdr, addr = parseaddr(value)
                name = decode_str(addr)
                # value = name + ' < ' + addr + ' > '
                value = name
                info.append(value)
        print(header + ':' + value)
    return info[0],value


# 头部信息已取出


# 获取邮件的字符编码,首先在message中寻找编码,如果没有,就在header的Content-Type中寻找
def guess_charset(msg):
    charset = msg.get_charset()
    if charset is None:
        content_type = msg.get('Content-Type', '').lower()
        pos = content_type.find('charset=')
        if pos >= 0:
            charset = content_type[pos + 8:].strip()
    return charset


# 邮件正文部分
# 取附件
# 邮件的正文部分在生成器中,msg.walk()
# 如果存在附件,则可以通过.get_filename()的方式获取文件名称

def get_file(msg):
    for part in msg.walk():
        filename = part.get_filename()
        if filename != None:  # 如果存在附件
            filename = decode_str(filename)  # 获取的文件是乱码名称,通过一开始定义的函数解码
            data = part.get_payload(decode=True)  # 取出文件正文内容
            # 此处可以自己定义文件保存位置
            if '划拨保费' in filename:
                path = r'C:\rpa'+'\\'+ filename
                print(path)
                f = open(path, 'wb')
                f.write(data)
                f.close()
                print(filename, 'download')
            else:
                print('请正确命名并重新发送!')


def get_content(msg):
    for part in msg.walk():
        content_type = part.get_content_type()
        charset = guess_charset(part)
        # 如果有附件,则直接跳过
        if part.get_filename() != None:
            continue
        email_content_type = ''
        content = ''
        if content_type == 'text/plain':
            email_content_type = 'text/plain'
        elif content_type == 'html':
            print('html 格式 跳过')
            continue  # 不要html格式的邮件
            email_content_type = 'html'
        if charset:
            try:
                content = part.get_payload(decode=True).decode(charset)
            except AttributeError:
                print('type error')
            except LookupError:
                print("unknown encoding: utf-8")
        if email_content_type == '':
            continue
            # 如果内容为空,也跳过
        print(email_content_type + ' -----邮件正文内容:  ' + content)
        #客户名称:张三;联系方式:123456789;邮箱:[email protected];ESN:wwwwweeeessssnnnnn;
        #print (content.split(';'))
        name = (content.split(';')[0]).split(':')[1]
        print ('客户名称:'+ name)
        tel = (content.split(';')[1]).split(':')[1]
        print ('联系方式:'+ tel)
        email = (content.split(';')[2]).split(':')[1]
        print ('邮箱:'+ email)
        ESN = (content.split(';')[3]).split(':')[1]
        print ('ESN:'+ ESN)
        #return name,tel,email,ESN
        #写入表格
        data_write(file_path, name, tel, email, ESN)
        return num + 2  # 作为发送邮件的循环条件,小于num+2行时


#写入已有的表格中
def data_write(file_path, name,tel,email,ESN):
    #file_home = r'E:\RPA\test\License\ESN1.xlsx'
    #file_home = 'ESN1.xlsx'
    print("----开始写入第" + str(num) + "条数据到表格中--------------------")
    wb = load_workbook(filename=file_path)  # 打开excel文件
    #wb = load_workbook(file_path)
    #sheet_ranges = wb['sheet1']
    #print(sheet_ranges['A1'].value)  # 打印A1单元格的值
    ws = wb[u'sheet1']  # 根据Sheet1这个sheet名字来获取该sheet
    #根据num参数攻取的符合要求的邮件数量,
    i = num
    name_l = 1
    tel_l = 3
    email_l = 4
    ESN_l = 5
    ws['A1'] = '序号'
    ws['B1'] = '客户名称'
    ws['C1'] = '备注'
    ws['D1'] = '联系方式'
    ws['E1'] = '邮箱'
    ws['F1'] = 'ESN号'    
    ws['G1'] = '申请时间'
    ws['H1'] = '文件路径'
    ws["A%d" % (i + 1)].value = i     #序号列
    ws["B%d" % (i + 1)] = name
    ws["C%d" % (i + 1)] = '重新申请'
    ws["D%d" % (i + 1)] = tel
    ws["E%d" % (i + 1)] = email
    ws["F%d" % (i + 1)] = ESN

    print("----写入到表格第"+str(num) + "条数据,姓名:"+name+"  完成--------------------")

    # 对固定单元格修改
    #ws['c3'] = '1991/11/12'
    wb.save(file_path)

#新创建一个表格,每次都会将表格之前的数据删除
def new_excel(file_path):
    f = xlwt.Workbook()
    sheet1 = f.add_sheet(u'sheet1', cell_overwrite_ok=True)  # 创建sheet
    # 将数据写入第 i 行,第 j 列
    #i = num
    name_l = 1
    tel_l = 3
    email_l = 4
    ESN_l = 5
    sheet1.write(0, 0, label='序号')
    sheet1.write(0, 1, label='客户名称')
    sheet1.write(0, 2, label='备注')
    sheet1.write(0, 3, label='联系方式')
    sheet1.write(0, 4, label='邮箱')
    sheet1.write(0, 5, label='ESN号')
    sheet1.write(0, 6, label='申请时间')
    sheet1.write(0, 7, label='文件路径')
    #开始循环填入姓名、邮箱、电话、ESN
    #sheet1.write(i, name_l, label = name)
    #sheet1.write(i, tel_l, label = tel)
    #sheet1.write(i, email_l, label = email)
    #sheet1.write(i, ESN_l, label = ESN)
    f.save(file_path)


def write_excel(file_path, name,tel,email,ESN):
    f = xlwt.Workbook()
    sheet1 = f.add_sheet(u'sheet1')  # 创建sheet,不覆盖
    # 将数据写入第 i 行,第 j 列
    i = num
    name_l = 1
    tel_l = 3
    email_l = 4
    ESN_l = 5
    #开始循环填入姓名、邮箱、电话、ESN
    sheet1.write(i, name_l, label = name)
    sheet1.write(i, tel_l, label = tel)
    sheet1.write(i, email_l, label = email)
    sheet1.write(i, ESN_l, label = ESN)
    f.save(file_path)

#获取收件箱内容
def inbox_content(tt):
    email = '[email protected]'
    password = '密码'
    server = poplib.POP3_SSL('pop.exmail.qq.com')
    server.user(email)
    server.pass_(password)
    # 登录的过程
    resp, mails, octets = server.list()
    index = len(mails)  # 邮件的总数
    print(index)
    #保存邮件内容的表格路径
    path = cur_file_dir()
    print ("path------"+path)
    #file_path = r'E:\RPA\test\License\ESN.xlsx'
    file_path = path+'\ESN.xlsx'
    print("file_path------" + file_path)

    #符合条件的邮件数量
    num = 0
    # 此处的循环是取最近的几封邮件
    if index:
        if index > 20:
            begin_index = index-20
            end_index = index +1
        else:
            begin_index = 0
            end_index = index +1
        for i in range(begin_index, end_index):
            resp, lines, octets = server.retr(i)  # 取邮件
            msg_content = b'\r\n'.join(lines).decode('utf-8', 'ignore')
            msg = Parser().parsestr(msg_content)

            flag,content = get_header(msg)
            print(flag+"flag")
            print(content+">>>>")
            if content == 'ESN申请':

                num = num + 1
                print("--------第"+str(num) + "条主题'ESN申请',获取邮件内容填到表格中-----")
                #print("--------第"+str(num) + "条--------------------")
                get_file(msg)
                get_content(msg)
                server.dele(i)  # 删除邮件
                print ("删除邮件")

            else:
                print('主题不是“ESN申请”')
        print("----共发现" + str(num) + "条主题为'ESN申请'的邮件-----------")


        server.quit()

# 获取未读邮箱内容
if __name__ == '__main__':
    # 保存邮件内容的表格路径
    path = cur_file_dir()
    print("path------" + path)
    # file_path = r'E:\RPA\test\License\ESN.xlsx'
    file_path = path + '\ESN.xlsx'
    print("file_path------" + file_path)
    #先创建空白文件,保证每次执行时没有以前遗留数据
    #new_excel(file_path)
    #print("-------------------new_excel()方法后,file_path:" + file_path)


    # IMAP服务器地址,邮箱地址,密码,是否打开SSL加密
    with Imbox("imap.exmail.qq.com","[email protected]","输入邮箱密码",ssl=True) as imbox:
        #all_box_messages = imbox.messages()  #所有邮件
        unread_box_messages = imbox.messages(unread=True)   #未读邮件
        print("连接成功")  # 发件人
        num = 0   #符合条件的数量
        for uid, message in unread_box_messages:
            #print("主题:" + message.subject)
            if message.subject == 'ESN申请':

                num = num + 1
                print("主题:" + message.subject+",符合条件,将正文内容复制到表格中")
                print("复制到表格中")
                content = message.body['plain'][0]
                print("邮件正文:-----"+str(content))
                #print(message.sent_from)  #发件人
                #print(message.sent_to)  #收件人
                #print(message.subject)  #主题
                #print(message.date) #时间
                name = (content.split(';')[0]).split(':')[1]
                print('客户名称:' + name)
                tel = (content.split(';')[1]).split(':')[1]
                print('联系方式:' + tel)
                email = (content.split(';')[2]).split(':')[1]
                print('邮箱:' + email)
                ESN = (content.split(';')[3]).split(':')[1]
                print('ESN:' + ESN)
                # return name,tel,email,ESN
                # 写入表格
                #write_excel(file_path, name, tel, email, ESN)
                data_write(file_path, name, tel, email, ESN)
                #标记已读:imbox.mark_seen(uid),删除已读:imbox.delete(uid)
                imbox.mark_seen(uid)  # 标记为已读


            else:
                print("主题:'"+ message.subject+"'不符合要求")
                continue
        print("----共获取"+str(num)+"条主题为'ESN申请'的未读邮件------")

   # message.body['plain'] #文本格式内容
   # message.body['html']   #HTML格式内容

    #message.attacments


# 红旗邮件
#red_flagged_messages = imbox.messages(flagged=True)
# 某发件人邮件
#inbox_messages_from = imbox.messages(sent_from='[email protected]')
# 某收件人邮件
#inbox_messages_from = imbox.messages(sent_to='[email protected]')
# 根据日期筛选
#某天前 date__lt
#某天后 date__gt
#指定某一天date__on
#inbox_messages_before = imbox.messages(date__lt=datetime.date(2020, 5, 19))

你可能感兴趣的:(python接收未读邮件并将满足主题为XX的邮件正文存放到表格中)