imaplib 获取邮件,email解析邮件

config文件中存有路径
1 # config.py
2 FILE_PATH_PREFIX = os.getcwd() + '/static/'
3 FILE_PATH_PREFIX_ALIAS = "/static/"  
4 FILE_DOMAIN_PREFIX = 'http://0.0.0.0:8090'

 

utils.py中的 file_path 方法
1 # 根据当前时间创建的文件夹,先检测再创建;
2 def file_path(file_path):
3     dayTime = datetime.now().strftime('%Y-%m-%d')
4     pwd = file_path + dayTime + '/'
5     isExists = os.path.exists(pwd)
6     if not isExists:
7         os.makedirs(pwd)
8     return pwd

 

imaplib 获取邮件,email解析邮件
get_email()函数的参数根据项目实际情况传。

旧版内容:
  1 import imaplib
  2 import email
  3 import re
  4 import time
  5 from email.header import decode_header, Header
  6 from datetime import datetime, timedelta
  7 from email.utils import parseaddr
  8 import util
  9 from config import FILE_PATH_PREFIX, FILE_DOMAIN_PREFIX, FILE_PATH_PREFIX_ALIAS
 10 import os
 11 
 12 imaplib.Commands['ID'] = ('AUTH')
 13 
 14 
 15 def decode_data(content, added_encode=None):
 16     """解码"""
 17 
 18     def _decode(bytes_, msg_charset):
 19         try:
 20             if isinstance(bytes_, bytes):
 21                 return str(bytes_, encoding=msg_charset)
 22             else:
 23                 return str(bytes_).split(' ')[0]
 24         except Exception as e:
 25             return None
 26 
 27     encodes = ['UTF-8', 'GBK', 'GB2312']
 28     if added_encode:
 29         encodes = [added_encode] + encodes
 30     for encoding in encodes:
 31         if r'\u' in str(content):
 32             str_data = _decode(content, 'unicode-escape')
 33         else:
 34             str_data = _decode(content, encoding)
 35         if str_data is not None:
 36             return str_data
 37     return None
 38 
 39 
 40 def get_local_time_stamp(msg, date):
 41     """将邮箱时间转换为北京时间"""
 42     if date is None:
 43         if msg['Received']:
 44             date = msg['Received'].split(';')[-1].strip()
 45         else:
 46             return None
 47     if ',' not in date:
 48         date = msg['Received'].split(';')[-1].strip()
 49     result = re.search(r"[\-+]\d+", date)
 50     if result:
 51         time_area = result.group()
 52         symbol = time_area[0]
 53         offset = int(time_area[1]) + int(time_area[2])
 54         date_re = re.compile(r'[(](.*?)[)]', re.S)
 55         time_zone = re.findall(date_re, date)
 56         if time_zone:
 57             format_str = '%a, %d %b %Y %H:%M:%S ' + time_area + ' ({})'.format(time_zone[0])
 58         else:
 59             format_str = '%a, %d %b %Y %H:%M:%S ' + time_area
 60         if symbol == "+":
 61             utc_time = time.strptime(date.strip(), format_str)
 62             temps_time = datetime.fromtimestamp(time.mktime(utc_time))
 63             if offset > 8:
 64                 offset = offset - 8
 65             elif offset < 8:
 66                 offset = 8 - offset
 67             else:
 68                 offset = 0
 69             local_temps_time = temps_time + timedelta(hours=offset)
 70         else:
 71             utc_time = time.strptime(date.strip(), format_str)
 72             temps_time = datetime.fromtimestamp(time.mktime(utc_time))
 73             local_temps_time = temps_time + timedelta(hours=(offset + 8))
 74         return local_temps_time
 75     else:
 76         time_zone = date[-3:]
 77         format_str = '%a, %d %b %Y %H:%M:%S {}'.format(time_zone)
 78         utc_time = time.strptime(date.strip(), format_str)
 79         temps_time = datetime.fromtimestamp(time.mktime(utc_time))
 80         if time_zone == 'UTC' or time_zone == 'GMT':
 81             hours_ = 8
 82         elif time_zone == 'CDT':
 83             hours_ = 13
 84         else:
 85             hours_ = 0
 86         local_temps_time = temps_time + timedelta(hours=hours_)
 87         return local_temps_time
 88 
 89 
 90 def parse_email_body(message):
 91     """解析内容"""
 92     content_list = []
 93     for part in message.walk():
 94         if not part.is_multipart():
 95             charset = part.get_charset()
 96             contentType = part.get_content_type()
 97             if contentType == 'text/plain' or contentType == 'text/html':
 98                 mail_content = decode_data(part.get_payload(decode=True), charset)
 99                 content_list.append(mail_content)
100     for i in content_list:
101         if 'html' in i:
102             content = i
103             return content
104     return content_list[0]
105 
106 
107 def parse_email_annex(message, client_id, from_email, send_email, mail_subject, mail_content, email_time):
108     """ 解析保存附件 """
109     annex_list = []
110     for part in message.walk():
111         # 获取附件名称类型
112         file_name = part.get_filename()
113         if not part.is_multipart():
114             if file_name:
115                 # 附件内容,先检测是否已存有该附件再保存
116                 file_name = decode_header(Header(file_name))
117                 annex_name = file_name[0][0]
118                 if file_name[0][1]:
119                     value, charset = decode_header(str(annex_name, file_name[0][1]))[0]
120                     annex_name = decode_data(value, charset)
121                 pwd = util.file_path(FILE_PATH_PREFIX + 'annex/')
122                 id_ = str(int(time.time()))
123                 url_ = FILE_DOMAIN_PREFIX + FILE_PATH_PREFIX_ALIAS + 'annex/' + pwd.split('/')[-2] + '/' + id_ + '_' \
124                        + annex_name
125                 path_ = pwd + id_ + '_' + annex_name
126                 if not os.path.isfile(path_):
127                     fp = open(path_, 'wb')
128                     fp.write(part.get_payload(decode=True))
129                     fp.close()
130                 annex_list.append({'annexName': annex_name, 'annexUrl': url_, 'annexPath': path_})
131     return annex_list
132 
133 
134 def get_email(server, username, password, send_email, client_id, created_by):
135     """
136     获取邮件信息并保存
137     https://www.docs4dev.com/docs/zh/python/3.7.2rc1/all/library-imaplib.html
138     """
139     # if first_run:
140     #     mail_status = 'All'
141     #     mail_num = -30
142     # else:
143     #     mail_status = 'UnSeen'
144     #     mail_num = -10
145     try:
146         imap = imaplib.IMAP4_SSL(server)
147         try:
148             imap.login(username, password)
149         except Exception as e:
150             print('账号:{} 登录失败:{}'.format(username, e))
151         else:
152             # 通过遍历查看imap中有哪些mailbox的值可以选择:
153             # for i in imap.list()[1]:
154             #     print('i:', i)
155             # mailbox:INBOX(默认收件箱)/Drafts(草稿箱)/Junk(垃圾箱)/Trash(已删除)/Sent(已发送)
156             mail_box = ['INBOX']
157             # 针对网易邮箱被阻止:https://blog.csdn.net/jony_online/article/details/108638571
158             args = ("name", username, "contact", username, "version", "1.0.0", "vendor", "myclient")
159             imap._simple_command('ID', '("' + '" "'.join(args) + '")')
160             for i in mail_box:
161                 try:
162                     imap.select(mailbox=i)
163                     typ, data = imap.search(None, 'All')  # UnSeen 未读邮件
164                 except:
165                     imap.select()
166                     typ, data = imap.search(None, 'All')
167                 for num in data[0].split()[-10:]:
168                     typ, data = imap.fetch(num, '(RFC822)')
169                     str_message = decode_data(data[0][1])
170                     message = email.message_from_string(str_message)
171                     sub = message.get('subject')
172                     if sub:
173                         mail_subject = ''
174                         msgCharset = ''
175                         for i in range(len(decode_header(sub))):
176                             subject_, charset = decode_header(sub)[i]
177                             msgCharset = charset
178                             if charset is not None:
179                                 # subject_ = subject_.decode(charset)
180                                 subject_ = decode_data(subject_, charset)
181                                 mail_subject += subject_
182                             else:
183                                 subject_ = decode_data(subject_, charset)
184                                 mail_subject += subject_
185                         # print('mail_subject:', mail_subject)
186                         from_email = parseaddr(message.get('from'))[1]  # 发件人邮箱
187                         from_name = message.get('from').split('<')[0].strip()
188                         if '"' in from_name:
189                             from_name = from_name.strip('"')
190                         from_name = decode_data(decode_header(from_name)[0][0], msgCharset)  # 发件人名称
191                         # to_email = parseaddr(message.get('to'))[1]  # 收件人邮箱
192                         date_ = get_local_time_stamp(message, message.get('date'))
193                         if date_ is not None:
194                             email_time = date_.timestamp()  # 收件时间
195                         else:
196                             email_time = time.time()
197                         mail_content = parse_email_body(message)
198                         # 将获取到的客户端上的邮件改为已读状态
199                         # imap.store(num, '+FLAGS', '(\\Seen)')
200             imap.close()
201             imap.logout()
202     except:
203         pass
View Code

相关文章: