最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2021年09月13日 10:47:07   作者:Alan.hsiang  
IMAP是另一種讀取電子郵件的協(xié)議,IMAP是讀取郵件服務(wù)器的電子郵件與公布欄信息的方法,也就是說IMAP 允許客戶端的郵件程序存取遠(yuǎn)程的信息,這篇文章主要給大家介紹了關(guān)于Python如何利用IMAP實(shí)現(xiàn)郵箱客戶端功能的相關(guān)資料,需要的朋友可以參考下

概述

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

什么是IMAP?

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

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

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

同時(shí),IMAP可以只下載郵件的主題,只有當(dāng)您真正需要的時(shí)候,才會(huì)下載郵件的所有內(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郵箱的完整郵件地址

涉及知識點(diǎn)

在本示例中,涉及知識點(diǎn)如下所示:

  • imaplib模塊:此模塊實(shí)現(xiàn)通過IMAP【Internet Message Access Protocol,信息交互訪問協(xié)議】協(xié)議進(jìn)行郵箱的登錄,接收和發(fā)送等功能。
    • IMAP4_SSL(host='', port=IMAP4_SSL_PORT),通過此方法可以定義一個(gè)IMAP對象,需要對應(yīng)的服務(wù)器和端口號。
    • login(self, user, password),通過此方法實(shí)現(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')) 解析郵件接收時(shí)間
    • email.header.decode_header(msg.get('From'))[0][0] 解析發(fā)件人
    • email.header.decode_header(msg.get('Subject'))[0][0].decode(msgCharset) 解析郵件標(biāo)題
    • 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'  # 主機(jī)IP或者域名
    port = '993'  # 端口
    username = '********'  # 用戶名
    password = '**************'  # 密碼或授權(quán)碼
    imap = None  # 郵箱連接對象
 
    # mail_box = '**************'  # 郵箱名
 
    def __init__(self, host, port):
        """初始化方法"""
        self.host = host
        self.port = port
        # 初始化一個(gè)郵箱鏈接對象
        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')  # 返回一個(gè)元組,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ù)(消息體)
                        # 獲取郵件標(biāo)題并進(jìn)行進(jìn)行解碼,通過返回的元組的第一個(gè)元素我們得知消息的編碼
                        msgCharset = email.header.decode_header(msg.get('Subject'))[0][1]
                        # print('msg = ',msg)
                        # print('msgCharset= ',msgCharset)  # gb2312
                        recv_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)  # 獲取標(biāo)題并通過標(biāo)題進(jìn)行解碼
 
                        print("Message %s\n%s\n" % (num, subject))  # 打印輸出標(biāo)題
                        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)
            # 獲取郵件標(biāo)題并進(jìn)行進(jìn)行解碼,通過返回的元組的第一個(gè)元素我們得知消息的編碼
            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):
        """獲取時(shí)間"""
        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'  # 主機(jī)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)容在前臺(tá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'  # 主機(jī)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)):
            # 時(shí)間特殊處理
            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)
        # 明細(xì)
        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):
        """獲取郵件明細(xì)"""
        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('個(gè)人郵箱')
    root.geometry('760x580+200+200')
    root.setvar("bg", "red")
    app = Application(master=root)
    root.mainloop()

郵箱設(shè)置

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

如果通過郵箱賬戶密碼登錄時(shí),報(bào)如下錯(cuò)誤,則表示需要通過授權(quán)碼進(jìn)行登錄,如下所示:

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

總結(jié)

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

相關(guān)文章

  • Python實(shí)現(xiàn)給qq郵箱發(fā)送郵件的方法

    Python實(shí)現(xiàn)給qq郵箱發(fā)送郵件的方法

    這篇文章主要介紹了Python實(shí)現(xiàn)給qq郵箱發(fā)送郵件的方法,涉及Python郵件發(fā)送的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • 使用python加密主機(jī)文件幾種方法實(shí)現(xiàn)

    使用python加密主機(jī)文件幾種方法實(shí)現(xiàn)

    本文主要介紹了使用python加密主機(jī)文件幾種方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 終端能到import模塊 解決jupyter notebook無法導(dǎo)入的問題

    終端能到import模塊 解決jupyter notebook無法導(dǎo)入的問題

    這篇文章主要介紹了在終端能到import模塊 而在jupyter notebook無法導(dǎo)入的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • Pandas DataFrame中的tuple元素遍歷的實(shí)現(xiàn)

    Pandas DataFrame中的tuple元素遍歷的實(shí)現(xiàn)

    這篇文章主要介紹了Pandas DataFrame中的tuple元素遍歷的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 利用tkinter實(shí)現(xiàn)下拉框聯(lián)動(dòng)

    利用tkinter實(shí)現(xiàn)下拉框聯(lián)動(dòng)

    這篇文章主要介紹了利用tkinter實(shí)現(xiàn)下拉框聯(lián)動(dòng)問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • python中判斷字符串值是否為數(shù)字的方法

    python中判斷字符串值是否為數(shù)字的方法

    本文介紹了幾種判斷Python字符串是否為數(shù)字的方法,包括isdigit()、isnumeric()方法,以及使用try-except塊進(jìn)行類型轉(zhuǎn)換,對于更復(fù)雜的數(shù)字格式,還推薦使用正則表達(dá)式進(jìn)行匹配,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • Python學(xué)習(xí)小技巧之利用字典的默認(rèn)行為

    Python學(xué)習(xí)小技巧之利用字典的默認(rèn)行為

    這篇文章主要給大家介紹了Python學(xué)習(xí)小技巧之利用字典的默認(rèn)行為的相關(guān)資料,文中介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2017-05-05
  • 在Python中用get()方法獲取字典鍵值的教程

    在Python中用get()方法獲取字典鍵值的教程

    這篇文章主要介紹了在Python中用get()方法獲取字典鍵值的教程,是Python入門中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-05-05
  • python中re.findall()?的使用案例

    python中re.findall()?的使用案例

    re.findall()?函數(shù)是?python?中正則表達(dá)式模塊(re)的一個(gè)重要函數(shù),它可以根據(jù)正則表達(dá)式搜索字符串,并返回匹配的字符串列表,這篇文章給大家介紹了python中re.findall()?的使用案例,感興趣的朋友跟隨小編一起看看吧
    2023-09-09
  • python安裝pil庫方法及代碼

    python安裝pil庫方法及代碼

    在本篇內(nèi)容里我們給大家分享的是關(guān)于python安裝pil庫方法及代碼內(nèi)容,有此需要的朋友們可以參考下。
    2019-06-06

最新評論

马关县| 景泰县| 剑阁县| 文登市| 会东县| 调兵山市| 明水县| 怀宁县| 类乌齐县| 承德县| 长子县| 关岭| 内乡县| 桐梓县| 兴隆县| 齐河县| 晋江市| 高邑县| 民权县| 望城县| 吉木萨尔县| 山西省| 兰考县| 常州市| 新昌县| 重庆市| 萍乡市| 阿图什市| 常山县| 社会| 河曲县| 兖州市| 三原县| 信阳市| 沽源县| 浦县| 郸城县| 绥中县| 阿克| 新乡市| 宁明县|