人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動態(tài)

Python如何利用IMAP實現(xiàn)郵箱客戶端功能

發(fā)布日期:2022-01-04 15:19 | 文章來源:站長之家

概述

在日常工作生活中,都是利用個人或公司的郵箱客戶端進行收發(fā)郵件,那么如何打造一款屬于自己的郵箱客戶端呢?本文以一個簡單的小例子,簡述如何通過Pyhton的imaplib和email兩大模塊,實現(xiàn)郵件的接收并展示,僅供學(xué)習(xí)分享使用,如有不足之處,還請指正。

什么是IMAP?

IMAP,即InternetMessageAccessProtocol(互聯(lián)網(wǎng)郵件訪問協(xié)議),您可以通過這種協(xié)議從郵件服務(wù)器上獲取郵件的信息、下載郵件等。IMAP與POP類似,都是一種郵件獲取協(xié)議。

IMAP和POP有什么區(qū)別?

POP允許電子郵件客戶端下載服務(wù)器上的郵件,但是您在電子郵件客戶端的操作(如:移動郵件、標記已讀等),這是不會反饋到服務(wù)器上的,比如:您通過電子郵件客戶端收取了QQ郵箱中的3封郵件并移動到了其他文件夾,這些移動動作是不會反饋到服務(wù)器上的,也就是說,QQ郵箱服務(wù)器上的這些郵件是沒有同時被移動的 。但是IMAP就不同了,電子郵件客戶端的操作都會反饋到服務(wù)器上,您對郵件進行的操作(如:移動郵件、標記已讀等),服務(wù)器上的郵件也會做相應(yīng)的動作。也就是說,IMAP是“雙向”的。

同時,IMAP可以只下載郵件的主題,只有當您真正需要的時候,才會下載郵件的所有內(nèi)容。

如何設(shè)置IMAP服務(wù)的SSL加密方式?

使用SSL的通用配置如下:

  • 接收郵件服務(wù)器:imap.qq.com,使用SSL,端口號993
  • 發(fā)送郵件服務(wù)器:smtp.qq.com,使用SSL,端口號465或587
  • 賬戶名:您的QQ郵箱賬戶名(如果您是VIP帳號或Foxmail帳號,賬戶名需要填寫完整的郵件地址)
  • 密碼:您的QQ郵箱密碼
  • 電子郵件地址:您的QQ郵箱的完整郵件地址

涉及知識點

在本示例中,涉及知識點如下所示:

  • imaplib模塊:此模塊實現(xiàn)通過IMAP【Internet Message Access Protocol,信息交互訪問協(xié)議】協(xié)議進行郵箱的登錄,接收和發(fā)送等功能。
    • IMAP4_SSL(host='', port=IMAP4_SSL_PORT),通過此方法可以定義一個IMAP對象,需要對應(yīng)的服務(wù)器和端口號。
    • login(self, user, password),通過此方法實現(xiàn)對應(yīng)郵箱的登錄,傳入指定的賬號,密碼即可。
    • select(self, mailbox='INBOX', readonly=False) 選擇收件箱
    • search(self, charset, *criteria) 查找獲取郵箱數(shù)據(jù)
    • fetch(self, message_set, message_parts) 通過郵件編號,查找具體的郵件內(nèi)容
  • email模塊:此模塊主要用于郵件的解析功能
    • message_from_string(s, *args, **kws) , 獲取解析數(shù)據(jù)消息體
    • email.header.decode_header(msg.get('Subject'))[0][1] 解析編碼方式
    • email.header.decode_header(msg.get('Date')) 解析郵件接收時間
    • email.header.decode_header(msg.get('From'))[0][0] 解析發(fā)件人
    • email.header.decode_header(msg.get('Subject'))[0][0].decode(msgCharset) 解析郵件標題
    • email.utils.parseaddr(msg.get('Content-Transfer-Encoding'))[1] 解析郵件傳輸編碼

示例效果圖

示例分為兩部分,左邊是郵件列表,右邊是郵件內(nèi)容,如下所示:

核心代碼

郵件幫助類,主要包括郵件的接收,具體郵件內(nèi)容的解析等功能,如下所示:

import imaplib
import email
import datetime
 
 
class EmailUtil:
 """
 Email幫助類
 """
 host = 'imap.qq.com'  # 主機IP或者域名
 port = '993'  # 端口
 username = '********'  # 用戶名
 password = '**************'  # 密碼或授權(quán)碼
 imap = None  # 郵箱連接對象
 
 # mail_box = '**************'  # 郵箱名
 
 def __init__(self, host, port):
  """初始化方法"""
  self.host = host
  self.port = port
  # 初始化一個郵箱鏈接對象
  self.imap = imaplib.IMAP4_SSL(host=self.host, port=int(self.port))
 
 def login(self, username, password):
  """登錄"""
  self.username = username
  self.password = password
  self.imap.login(user=self.username, password=self.password)
 
 def get_mail(self):
  """獲取郵件"""
  # self.mail_box = mail_box
  email_infos = []
  if self.imap is not None:
self.imap.select(readonly=False)
typ, data = self.imap.search(None, 'ALL')  # 返回一個元組,data為此郵箱的所有郵件數(shù)據(jù)
#  數(shù)據(jù)格式 data =  [b'1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18']
if typ == 'OK':
 for num in data[0].split():
  if int(num) > 10:# 超過20,退出循環(huán),不輸出break
  typ1, data1 = self.imap.fetch(num, '(RFC822)')  # 通過郵箱編號和選擇獲取數(shù)據(jù)
  if typ1 == 'OK':print('**********************************begin******************************************')msg = email.message_from_string(data1[0][1].decode("utf-8"))  # 用email庫獲取解析數(shù)據(jù)(消息體)# 獲取郵件標題并進行進行解碼,通過返回的元組的第一個元素我們得知消息的編碼msgCharset = email.header.decode_header(msg.get('Subject'))[0][1]# print('msg = ',msg)# print('msgCharset= ',msgCharset)  # gb2312recv_date = self.get_email_date(email.header.decode_header(msg.get('Date')))mail_from = email.header.decode_header(msg.get('From'))[0][0]if type(mail_from) == bytes:
mail_from = mail_from.decode(msgCharset)
 mail_to = email.header.decode_header(msg.get('To'))[0][0]subject = email.header.decode_header(msg.get('Subject'))[0][0].decode(msgCharset)  # 獲取標題并通過標題進行解碼
 print("Message %s\n%s\n" % (num, subject))  # 打印輸出標題print('mail_from:' + mail_from + ' mail_to:' + mail_to + ' recv_date:' + str(recv_date))# # 郵件內(nèi)容# for part in msg.walk():#  if not part.is_multipart():#name = part.get_param("name")#if not name:  # 如果郵件內(nèi)容不是附件可以打印輸出# print(part.get_payload(decode=True).decode(msgCharset))# print('***********************************end*****************************************')email_info = {
"num": num,
"subject": subject,
"recv_date": recv_date,
"mail_to": mail_to,
"mail_from": mail_from}email_infos.append(email_info)
  else:
print('請先初始化并登錄')
  return email_infos
 
 def get_email_content(self, num):
  content = None
  typ1, data1 = self.imap.fetch(num, '(RFC822)')  # 通過郵箱編號和選擇獲取數(shù)據(jù)
  if typ1 == 'OK':
print('**********************************begin******************************************')
msg = email.message_from_string(data1[0][1].decode("utf-8"))  # 用email庫獲取解析數(shù)據(jù)(消息體)
print(msg)
# 獲取郵件標題并進行進行解碼,通過返回的元組的第一個元素我們得知消息的編碼
msgCharset = email.header.decode_header(msg.get('Subject'))[0][1]
# transfer_encoding = email.header.decode_header(msg.get('Content-Transfer-Encoding'))
transfer_encoding = email.utils.parseaddr(msg.get('Content-Transfer-Encoding'))[1]
print("transfer_encoding:",transfer_encoding)
print("charset:",msgCharset)
# 郵件內(nèi)容
for part in msg.walk():
 if not part.is_multipart():
  name = part.get_param("name")
  if not name:  # 如果郵件內(nèi)容不是附件可以打印輸出if transfer_encoding == '8bit':
content = part.get_payload(decode=False)else:
content = part.get_payload(decode=True).decode(msgCharset)
 
print(content)
print('***********************************end*****************************************')
  return content
 
 def get_email_date(self, date):
  """獲取時間"""
  utcstr = date[0][0].replace('+00:00', '')
  utcdatetime = None
  localtimestamp = None
  try:
utcdatetime = datetime.datetime.strptime(utcstr, '%a, %d %b %Y %H:%M:%S +0000 (GMT)')
localdatetime = utcdatetime + datetime.timedelta(hours=+8)
localtimestamp = localdatetime.timestamp()
  except:
try:
 utcdatetime = datetime.datetime.strptime(utcstr, '%a, %d %b %Y %H:%M:%S +0800 (CST)')
 localtimestamp = utcdatetime.timestamp()
except:
 utcdatetime = datetime.datetime.strptime(utcstr, '%a, %d %b %Y %H:%M:%S +0800')
 localtimestamp = utcdatetime.timestamp()
  return localtimestamp
 
 
if __name__ == '__main__':
 host = 'imap.qq.com'  # 主機IP或者域名
 port = '993'  # 端口
 username = '********'  # 用戶名
 password = '**************'  # 密碼
 mail_box = '**************'  # 郵箱名
 eamil_util = EmailUtil(host=host, port=port)
 eamil_util.login(username=username, password=password)
 eamil_util.get_mail()
 print('done')

郵件展示類,主要用于郵件內(nèi)容在前臺頁面的展示,如下所示:

from tkinter import *
from tkinterie.tkinterIE import WebView
from test_email import EmailUtil
import time
import os
 
class Application(Frame):
 email_util = None
 total_line= 0
 
 def __init__(self, master=None):
  '''初始化方法'''
  super().__init__(master)  # 調(diào)用父類的初始化方法
  host = 'imap.qq.com'  # 主機IP或者域名
  port = '993'  # 端口
  username = '*********'  # 用戶名
  password = '**************'  # 密碼或授權(quán)碼
  self.email_util = EmailUtil(host=host, port=port)
  self.email_util.login(username=username, password=password)
  self.master = master
  # self.pack(side=TOP, fill=BOTH, expand=1)  # 此處填充父窗體
  self.create_widget()
 
 def create_widget(self):
  self.img_logo = PhotoImage(file="logo.png")
  self.btn_logo = Button(image=self.img_logo , bg='#222E3C')
  self.btn_logo.grid(row=0, column=0, sticky=N + E + W+S)
  # 收件箱初始化
  records = self.email_util.get_mail()
  for i in range(len(records)):
# 時間特殊處理
recv_date =  time.strftime("%Y-%m-%d", time.localtime(records[i]["recv_date"]))
subject = "{0}{1}".format(recv_date, records[i]["subject"])
print(subject)
num = records[i]["num"]
btn_subject = Button(self.master, text=subject,height=2, width=30, bg=("#F0FFFF" if i%2==0 else "#E6E6FA"), anchor='w',command=lambda num=num: self.get_email_content(num) )
btn_subject.grid(row=(i + 1), column=0, padx=2, pady=1)
  # 明細
  self.total_line=i
  self.web_view = WebView(self.master, width=530, height=560)
  self.web_view.grid(row=0, column=1, rowspan=(i+2), padx=2, pady=5, sticky=N + E + W)
 
 def get_email_content(self,num):
  """獲取郵件明細"""
  content = self.email_util.get_email_content(num)
  print(content)
  if content.find('GBK')>0 or content.find('gbk')>0 or content.find('cnblogs')>0:
print('1-1111')
# content = content.encode().decode('gbk')
  # print(content)
  self.save_data(content)
  abs_path =  os.path.abspath("content.html")
  self.web_view= WebView(self.master, width=530, height=560,url="file://"+abs_path)
  self.web_view.grid(row=0, column=1, rowspan=(self.total_line + 2), padx=5, pady=5, sticky=N + E + W)
 
 
 def save_data(self,content):
  """保存數(shù)據(jù)"""
  with open('content.html', 'w', encoding='utf-8') as f:
f.write(content)
 
 
if __name__ == '__main__':
 root = Tk()
 root.title('個人郵箱')
 root.geometry('760x580+200+200')
 root.setvar("bg", "red")
 app = Application(master=root)
 root.mainloop()

郵箱設(shè)置

如果要使用IMAP協(xié)議訪問郵箱服務(wù)進行收發(fā)郵件,則必須進行郵箱設(shè)置,路徑:登錄郵箱-->設(shè)置-->賬戶-->POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服務(wù),如下所示:

如果通過郵箱賬戶密碼登錄時,報如下錯誤,則表示需要通過授權(quán)碼進行登錄,如下所示:

溫馨提示:在第三方登錄QQ郵箱,可能存在郵件泄露風(fēng)險,甚至危害Apple ID安全,建議使用QQ郵箱手機版登錄。

總結(jié)

到此這篇關(guān)于Python如何利用IMAP實現(xiàn)郵箱客戶端功能的文章就介紹到這了,更多相關(guān)Python IMAP實現(xiàn)郵箱客戶端內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!

版權(quán)聲明:本站文章來源標注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問服務(wù)

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部