刚开始用的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))