122 lines
4.3 KiB
Python
122 lines
4.3 KiB
Python
import base64
|
||
import email
|
||
import email.header
|
||
import requests
|
||
import imaplib
|
||
|
||
import poplib
|
||
|
||
|
||
# 1. 使用refresh_token获取access_token
|
||
def get_accesstoken(refresh_token,client_id):
|
||
data = {
|
||
'client_id': client_id,
|
||
'grant_type': 'refresh_token',
|
||
'refresh_token': refresh_token
|
||
}
|
||
ret = requests.post('https://login.microsoftonline.com/consumers/oauth2/v2.0/token', data=data)
|
||
print(ret.text)
|
||
print(ret.json()['refresh_token'])
|
||
return ret.json()['access_token']
|
||
|
||
|
||
def generate_auth_string(user, token):
|
||
auth_string = f"user={user}\1auth=Bearer {token}\1\1"
|
||
return auth_string
|
||
|
||
|
||
def tuple_to_str(tuple_):
|
||
"""
|
||
元组转为字符串输出
|
||
:param tuple_: 转换前的元组,QQ邮箱格式为(b'\xcd\xf5\xd4\xc6', 'gbk')或者(b' <XXXX@163.com>', None),163邮箱格式为('<XXXX@163.com>', None)
|
||
:return: 转换后的字符串
|
||
"""
|
||
if tuple_[1]:
|
||
out_str = tuple_[0].decode(tuple_[1])
|
||
else:
|
||
if isinstance(tuple_[0], bytes):
|
||
out_str = tuple_[0].decode('gbk')
|
||
else:
|
||
out_str = tuple_[0]
|
||
return out_str
|
||
|
||
|
||
def fetch_email_body(mail, item):
|
||
status, msg_data = mail.fetch(item, "(RFC822)")
|
||
for response_part in msg_data:
|
||
if isinstance(response_part, tuple):
|
||
# 解码邮件
|
||
msg = email.message_from_bytes(response_part[1])
|
||
|
||
# 获取邮件主题
|
||
subject, encoding = email.header.decode_header(msg["Subject"])[0]
|
||
if isinstance(subject, bytes):
|
||
# 如果是字节,则解码
|
||
subject = subject.decode(encoding if encoding else "utf-8")
|
||
print("Subject:", subject)
|
||
# 获取发件人
|
||
from_ = msg.get("From")
|
||
print("From:", from_)
|
||
try:
|
||
if msg.is_multipart():
|
||
for part in msg.walk():
|
||
content_type = part.get_content_type()
|
||
content_disposition = str(part.get("Content-Disposition"))
|
||
|
||
if content_type == "text/plain" and "attachment" not in content_disposition:
|
||
body = part.get_payload(decode=True).decode()
|
||
return body
|
||
return ''
|
||
else:
|
||
body = msg.get_payload(decode=True).decode()
|
||
return body
|
||
except Exception as e:
|
||
return ''
|
||
|
||
|
||
def getmail(sel, mail):
|
||
mail.select(sel)
|
||
status, messages = mail.search(None, 'ALL') # UNSEEN 为未读邮件
|
||
all_emails = messages[0].split()
|
||
print(all_emails)
|
||
for item in all_emails:
|
||
print(fetch_email_body(mail, item))
|
||
|
||
# 2. 使用访问令牌连接 IMAP
|
||
def connect_imap(emailadr, access_token):
|
||
mail = imaplib.IMAP4_SSL('outlook.live.com')
|
||
mail.authenticate('XOAUTH2', lambda x: generate_auth_string(emailadr, access_token))
|
||
print('读取收件箱')
|
||
getmail('INBOX', mail) # 读取收件箱
|
||
print('读取垃圾箱')
|
||
getmail('Junk', mail) # 读取垃圾箱
|
||
# 关闭连接
|
||
mail.logout()
|
||
|
||
|
||
def connect_pop3(emailadr, access_token):
|
||
server = poplib.POP3_SSL('outlook.live.com')
|
||
token=generate_auth_string(emailadr, access_token)
|
||
encoded_auth_string = base64.b64encode(token.encode("utf-8")).decode("utf-8")
|
||
server._shortcmd(f'AUTH XOAUTH2')
|
||
server._shortcmd(f'{encoded_auth_string}')
|
||
print(server.list()[1])
|
||
server.quit()
|
||
|
||
|
||
# 主流程
|
||
if __name__ == '__main__':
|
||
client_id = '9e5f94bc-e8a4-4e73-b8be-63364c29d753'
|
||
emailadr = 'eedbbfdd186@outlook.com'
|
||
refresh_token ='M.C544_BL2.0.U.-CmrNXHVufVZdj1*CaDuSw4WSQYVfF7ILMi4XYHeVQ!YJm56uJO5HPG9I2bOJIRrS3c5FgP9sDKB*HjA3O6wVY4Cr7hzNGWjujT*xZ5k4gOjRDVXx9ocaY1bf5J2HZgAoBJYjFq76*3h2xddMEGqp7iFjYDo3B9rcfRGh!G6rJ38vkWBSGw!7hcj21IWdZD!eIZqCx1o2tDrzeH*fRnuf*DoTQEFCDnFpCoulmQHDUBEFiBT8H*TzupejEgWTmXewN9tpcQwFituIbGScsDWdRuB5pcF63p7jazZdeZ8Bpa7pQb5Fc4mYUSwQS4Qx9CNNMYnwYuhiAVEXPcoppWCA7WXF!bgOxa7IuZASnWMiC!jqUu77KnwrHWZD14SDrFfwBQ$$'
|
||
print(f'clientID:{client_id}')
|
||
print(f'邮箱地址:{emailadr}')
|
||
print(f'refresh_token:{refresh_token}')
|
||
access_token = get_accesstoken(refresh_token,client_id)
|
||
print("获取的访问令牌:", access_token)
|
||
# 连接 IMAP
|
||
print('IMAP测试')
|
||
connect_imap(emailadr, access_token)
|
||
print('pop3测试')
|
||
connect_pop3(emailadr,access_token)
|