139 lines
4.4 KiB
Python
139 lines
4.4 KiB
Python
# -*- coding: utf-8 -*-
|
||
import poplib
|
||
import base64
|
||
import os
|
||
from email.parser import Parser
|
||
from email.header import decode_header
|
||
from email.utils import parseaddr
|
||
|
||
email_user = {
|
||
'李宗振': {
|
||
'email': '1986461823@qq.com',
|
||
'pwd': 'hoosihokeaqkifdf'
|
||
},
|
||
'吴操': {
|
||
'email': '2787668634@qq.com',
|
||
'pwd': 'jendjvizztqsdebb'
|
||
}
|
||
}
|
||
|
||
|
||
def email_users(dirname, emaildict):
|
||
# 判断文件夹是否存在不存在创建文件夹
|
||
dirpath = './{0}'.format(dirname)
|
||
if not os.path.exists(dirpath):
|
||
os.makedirs(dirpath)
|
||
|
||
# 连接到POP3服务器:
|
||
server = poplib.POP3("pop.qq.com")
|
||
# 可以打开或关闭调试信息:
|
||
server.set_debuglevel(1)
|
||
# 可选:打印POP3服务器的欢迎文字:
|
||
print(server.getwelcome().decode('utf-8'))
|
||
|
||
# 身份认证:
|
||
server.user(emaildict['email'])
|
||
# server.user("1986461823@qq.com")
|
||
# 非密码,qq邮箱登录第三方需要的授权码,可在qq邮箱设置里获得
|
||
server.pass_(emaildict['pwd'])
|
||
# server.pass_("hoosihokeaqkifdf")
|
||
|
||
# stat()返回邮件数量和占用空间:
|
||
print('Messages: %s. Size: %s' % server.stat())
|
||
# list()返回所有邮件的编号:
|
||
resp, mails, octets = server.list()
|
||
# 可以查看返回的列表类似[b'1 82923', b'2 2184', ...]
|
||
print(mails)
|
||
|
||
# 获取最新一封邮件, 注意索引号从1开始:
|
||
index = len(mails)
|
||
for i in range(1, index + 1):
|
||
resp, lines, octets = server.retr(i)
|
||
|
||
# lines存储了邮件的原始文本的每一行,
|
||
# 可以获得整个邮件的原始文本:
|
||
try:
|
||
msg_content = b'\r\n'.join(lines).decode('utf-8')
|
||
except:
|
||
continue
|
||
# 稍后解析出邮件:
|
||
msg = Parser().parsestr(msg_content)
|
||
|
||
print_info(msg, dirpath)
|
||
# 可以根据邮件索引号直接从服务器删除邮件:
|
||
# server.dele(index)
|
||
# 关闭连接:
|
||
server.quit()
|
||
|
||
|
||
def print_info(msg, dirpath, indent=0):
|
||
for part in msg.walk():
|
||
if part.get_content_maintype() == 'multipart' or part.get('Content-Disposition') is None:
|
||
continue
|
||
fileName = part.get_filename()
|
||
# 保存附件
|
||
if fileName:
|
||
filename = ''
|
||
transfer_encoding = part.get_all('Content-Transfer-Encoding')
|
||
if transfer_encoding and transfer_encoding[0] == 'base64':
|
||
filename_parts = fileName.split('?')
|
||
filename = base64.b64decode(filename_parts[3]).decode(filename_parts[1])
|
||
|
||
data = part.get_payload(decode=True)
|
||
if filename:
|
||
filename_path = dirpath + "/{0}".format(filename)
|
||
# 文件存在则直接跳过
|
||
if os.path.exists(filename_path):
|
||
continue
|
||
fEx = open(filename_path, 'wb')
|
||
fEx.write(data)
|
||
fEx.close()
|
||
if indent == 0:
|
||
for header in ['From', 'To', 'Subject']:
|
||
value = msg.get(header, '')
|
||
if value:
|
||
if header == 'Subject':
|
||
value = decode_str(value)
|
||
else:
|
||
hdr, addr = parseaddr(value)
|
||
name = decode_str(hdr)
|
||
value = u'%s <%s>' % (name, addr)
|
||
print('%s%s: %s' % (' ' * indent, header, value))
|
||
if (msg.is_multipart()):
|
||
parts = msg.get_payload()
|
||
for n, part in enumerate(parts):
|
||
print('%spart %s' % (' ' * indent, n))
|
||
print('%s--------------------' % (' ' * indent))
|
||
print_info(part, dirpath, indent + 1)
|
||
else:
|
||
content_type = msg.get_content_type()
|
||
if content_type == 'text/plain' or content_type == 'text/html':
|
||
content = msg.get_payload(decode=True)
|
||
charset = guess_charset(msg)
|
||
if charset:
|
||
pass
|
||
else:
|
||
print('%sAttachment: %s' % (' ' * indent, content_type))
|
||
|
||
|
||
def decode_str(s):
|
||
value, charset = decode_header(s)[0]
|
||
if charset:
|
||
value = value.decode(charset)
|
||
return value
|
||
|
||
|
||
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
|
||
|
||
|
||
if __name__ == '__main__':
|
||
for dirname, email_dict in email_user.items():
|
||
email_users(dirname, email_dict)
|