使用 Python 與 Gmail POPerver 對話
POP 是相對較舊的協定。第一個版本是在 1984 年指定的。至今仍在使用的版本 POP3 是在 1996 年指定的。為了嘗試一下,我開始連接到 Gmail POP3 伺服器。
第一步是尋找 POP3 設定 - 連接到哪個伺服器、連接哪個連接埠。谷歌引導我來到這裡,我在那裡找到了以下資訊。
pop.gmail.com
需要 SSL:是
埠:995
它提到需要 SSL。 25 年前,當我最後一次擺弄 POP 時,我還沒有處理過這個問題。我擔心這會讓人頭疼,但事實證明這並不是什麼挑戰;在 Python 文件的幫助下,我得到了這段程式碼。
import socket import ssl hostname = 'pop.gmail.com' context = ssl.create_default_context() with socket.create_connection((hostname, 995)) as sock: with context.wrap_socket(sock, server_hostname=hostname) as s: print(s.version())
它會連接,並告訴我正在使用的 SSL 版本......或其他什麼。偉大的成功!是時候開始與伺服器對話了。
借用 POP3 的官方 RFC,這是客戶端和伺服器之間的 POP3 對話範例/
C: <open connection> S: +OK POP3 server ready <1896.697170952@dbc.mtview.ca.us> C: USER mrose S: +OK mrose is a real hoopy frood C: PASS secret S: +OK mrose's maildrop has 2 messages (320 octets) C: STAT S: +OK 2 320 C: LIST S: +OK 2 messages (320 octets) S: 1 120 S: 2 200 S: . C: RETR 1 S: +OK 120 octets S: <the POP3 server sends message 1> S: . C: QUIT S: +OK dewey POP3 server signing off (maildrop empty) C: <close connection>
首先發生的是伺服器傳送問候語給客戶端。友好的。因此,我將添加程式碼以從伺服器接收訊息。
當您要求從套接字接收資料時,您必須指定緩衝區大小。文件建議使用 2 的冪,例如 4096。來自伺服器的許多回應將同時通過。有些不會;有些則不會。有時來自伺服器的訊息會在伺服器讀取時被破壞,即使還有更多訊息,緩衝區也可能不會填滿。
對於 POP3,判斷訊息是否已傳入的方法完全取決於傳入的訊息。大多數情況下,伺服器會傳送單行文字。 (正如我們稍後將再次看到的,它們在每行末尾都有一個回車符和換行符。)某些可能具有更長響應的訊息使用另一種方式來顯示它們已完成:單行上的句點就其本身而言。
import socket import ssl hostname = 'pop.gmail.com' context = ssl.create_default_context() with socket.create_connection((hostname, 995)) as sock: with context.wrap_socket(sock, server_hostname=hostname) as s: print(s.version()) data = s.read(4096) print(data)
再次運行,我們收到了問候。又一次巨大的成功!請注意,該行以“rn”結尾——回車符和換行符。
您必須將緩衝區大小傳遞給讀取方法。然後它將有一個緩衝區,其大小可用於從伺服器讀取資料——但不能保證一次有多少資料進入緩衝區。這意味著協議需要某種方式來指定訊息何時完成。有多種可能的策略。 POP 使用兩個:對於所有訊息,行都以 rn 結尾。對於短(一行)訊息,這就是所需要的。對於多行回應,一行上的句點表示訊息已完成。
TLSv1.3 b'+OK Gpop ready for requests from 2601:1c0:8301:b590:f408:d66a:3029:16ad dq2mb54750689ivb\r\n'
現在我們需要開始與伺服器對話。是時候創建 I/O(或 O/I)循環了;獲取一些用戶輸入並將其發送到伺服器。哎呀!我無法直接發送字串;這給了我一個類型錯誤。我需要將訊息轉換為位元組。 stringencode() 方法可以做到這一點(預設編碼 utf-8 工作正常)。
只是,當我運行它時——哎呀又來了!當我的消息發送到伺服器時沒有任何反應。因為我忘了來自客戶端的訊息也需要以 rn 結尾。另一個微小的調整給了我們:
import socket import ssl hostname = 'pop.gmail.com' context = ssl.create_default_context() with socket.create_connection((hostname, 995)) as sock: with context.wrap_socket(sock, server_hostname=hostname) as s: print(s.version()) while True: data = s.read(4096) print(data) msg = input() + "\r\n" s.send(msg.encode())
太好了,現在我可以嘗試登入了!
TLSv1.3 b'+OK Gpop ready for requests from 2601:1c0:8301:b590:f408:d66a:3029:16ad g4mb5147337iow\r\n' USER grokprogramming b'+OK send PASS\r\n' PASS trustno1 b'-ERR [AUTH] Application-specific password required: https://support.google.com/accounts/answer/185833\r\n'
好的,點擊該連結後,我將進入一個可以設定應用程式特定密碼的頁面。我遇到的一個潛在的障礙是:據我所知,您的帳戶必須啟用雙重認證,以便您能夠建立應用程式特定的密碼。為什麼我不在我們的 Lorde 2024 年開啟雙重認證?我不能說。我現在知道了。
有了應用程式特定的密碼(注意去掉空格),我就可以登入了!然後我將發出 STAT 命令,它會告訴我有多少訊息以及它們的總大小。之後,我將發出 LIST 命令,該命令將返回一個訊息列表,其中包含每個訊息的 ID 和大小。
TLSv1.3 b'+OK Gpop ready for requests from 2601:1c0:8301:b590:f408:d66a:3029:16ad e18mb76868856iow\r\n' USER grokprogramming b'+OK send PASS\r\n' PASS baygdsgkmihkckrb b'+OK Welcome.\r\n' STAT b'+OK 263 14191565\r\n' LIST b'+OK 263 messages (14191565 bytes)\r\n1 2778\r\n2 2947\r\n3 6558\r\n4 9864\r\n5 35997\r\n6 45462\r\n7 45462\r\n8 63894\r\n9 11487\r\n10 74936\r\n11 74925\r\n12 11632\r\n13 32392\r\n14 74997\r\n15 51961\r\n16 15375\r\n17 46513\r\n18 21519\r\n19 15966\r\n20 27258\r\n21 28503\r\n22 35615\r\n23 86353\r\n24 280'
我在程式碼中遇到了一個錯誤。 LIST 的回應跨越多行,在這種情況下,將需要多次緩衝區讀取。整個訊息將以單獨一行的句點結束。在這裡,我已經收到了一個緩衝區的訊息,現在我必須按回車鍵並向伺服器發送一條空白訊息,以便程式碼前進到循環的下一次迭代並再次從緩衝區讀取。
我將調整程式碼,以便使用者始終可以選擇是否再次從緩衝區讀取。我還將最終解碼從伺服器傳入的字節,以便文字呈現得更好。
import socket import ssl hostname = 'pop.gmail.com' context = ssl.create_default_context() with socket.create_connection((hostname, 995)) as sock: with context.wrap_socket(sock, server_hostname=hostname) as s: print(s.version()) while True: data = s.read(4096) print(data.decode()) while input("more? y/[n]: ") == "y": data = s.read(4096) print(data.decode()) msg = input("> ") + "\r\n" s.send(msg.encode())
這是一個完整的會話,包括檢索電子郵件和發送斷開連接訊息。
> USER grokprogramming +OK send PASS more? y/[n]: > PASS trustno1 +OK Welcome. more? y/[n]: > STAT +OK 263 14191565 more? y/[n]: > LIST +OK 263 messages (14191565 bytes) 1 2778 2 2947 3 6558 <...> 260 41300 261 114059 262 174321 263 39206 . more? y/[n]: > RETR 1 +OK message follows MIME-Version: 1.0 Received: by 10.76.81.230; Thu, 28 Jun 2012 20:21:50 -0700 (PDT) Date: Thu, 28 Jun 2012 20:21:50 -0700 Message-ID: <CADBp03TWFOKcTOaK_0P7VV2GB+TZsoSd_W4G5nZKKs7pdk6cWQ@mail.gmail.com> Subject: Customize Gmail with colors and themes From: Gmail Team <mail-noreply@google.com> To: Grok Programming <grokprogramming@gmail.com> Content-Type: multipart/alternative; boundary=e0cb4e385592f8025004c393f2b4 --e0cb4e385592f8025004c393f2b4 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable To spice up your inbox with colors and themes, check out the Themes tab under Settings. Customize Gmail =BB <https://mail.google.com/mail/#settings/themes> Enjoy! - The Gmail Team [image: Themes thumbnails] Please note that Themes are not available if you're using Internet Explorer 6.0. To take advantage of the latest Gmail features, please upgrade to a fully supported browser<http://support.google.com/mail/bin/answer.py?answer=3D6557&hl=3Den&= utm_source=3Dwel-eml&utm_medium=3Deml&utm_campaign=3Den> .. --e0cb4e385592f8025004c393f2b4 Content-Type: text/html; charset=ISO-8859-1 more? y/[n]: y <html> <font face="Arial, Helvetica, sans-serif"> <p>To spice up your inbox with colors and themes, check out the Themes tab under Settings.</p> <table cellpadding="0" cellspacing="0"> <col style="width: 1px;"/> <col/> <col style="width: 1px;"/> <tr> <td></td> <td height="1px" style="background-color: #ddd"></td> <td></td> </tr> <tr> <td style="background-color: #ddd"></td> <td background="https://mail.google.com/mail/images/welcome-button-background.png" style="background-color: #ddd; background-repeat: repeat-x; padding: 10px; font-size: larger"> <a href="https://mail.google.com/mail/#settings/themes" style="font-weight: bold; color: #000; text-decoration: none; display: block;"> Customize Gmail »</a> </td> <td style="ba more? y/[n]: y ckground-color: #ddd"></td> </tr> <tr> <td></td> <td height="1px" style="background-color: #ddd"></td> <td></td> </tr> </table> <p>Enjoy!</p> <p>- The Gmail Team</p> <img width="398" height="256" src="https://mail.google.com/mail/images/gmail_themes_2.png" alt="Themes thumbnails" /> <p><font size="-2" color="#999">Please note that Themes are not available if you're using Internet Explorer 6.0. To take advantage of the latest Gmail features, please <a href="http://support.google.com/mail/bin/answer.py?answer=6557&hl=en&utm_source=wel-eml&utm_medium=eml&utm_campaign=en"><font color="#999"> upgrade to a fully supported browser</font></a>.</font></p> </font> </html> --e0cb4e385592f8025004c393f2b4-- . more? y/[n]: > QUIT +OK Farewell. more? y/[n]: >
Yet another great success! I was able to log in to the POP3 server and retrieve a message. The script in its current state is pretty flexible, but it requires a lot of work from the user. I'll make a few final tweaks to make interacting with the POP3 server a little easier: if the user starts a message to the server with a "!" it will be stripped out, but the script will read in data from the server until it gets to a period on a line by itself -- in other words, for commands with long responses. No "!" and the script will read in a single line, looking for the \r\n characters.
import socket import ssl hostname = 'pop.gmail.com' context = ssl.create_default_context() def read_until(s, eom): # read into the buffer at least once data = s.read(4096) # continue reading until end of message while data[-len(eom):] != eom: data += s.read(4096) # return incoming bytes decoded to a string return data.decode() def read_single_line(s): return read_until(s, b"\r\n") def read_muli_line(s): return read_until(s, b"\r\n.\r\n") with socket.create_connection((hostname, 995)) as sock: with context.wrap_socket(sock, server_hostname=hostname) as s: print(s.version()) print(read_single_line(s)) msg = input("> ") # empty msg will close connection while msg != "": if msg[0] == "!": msg = msg[1:] long = True else: long = False msg += "\r\n" s.send(msg.encode()) if long: print(read_muli_line(s)) else: print(read_single_line(s)) msg = input("> ") s.close()
以上是使用 Python 與 Gmail POPerver 對話的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undress AI Tool
免費脫衣圖片

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

多態是Python面向對象編程中的核心概念,指“一種接口,多種實現”,允許統一處理不同類型的對象。 1.多態通過方法重寫實現,子類可重新定義父類方法,如Animal類的speak()方法在Dog和Cat子類中有不同實現。 2.多態的實際用途包括簡化代碼結構、增強可擴展性,例如圖形繪製程序中統一調用draw()方法,或遊戲開發中處理不同角色的共同行為。 3.Python實現多態需滿足:父類定義方法,子類重寫該方法,但不要求繼承同一父類,只要對象實現相同方法即可,這稱為“鴨子類型”。 4.注意事項包括保持方

參數(parameters)是定義函數時的佔位符,而傳參(arguments)是調用時傳入的具體值。 1.位置參數需按順序傳遞,順序錯誤會導致結果錯誤;2.關鍵字參數通過參數名指定,可改變順序且提高可讀性;3.默認參數值在定義時賦值,避免重複代碼,但應避免使用可變對像作為默認值;4.args和*kwargs可處理不定數量的參數,適用於通用接口或裝飾器,但應謹慎使用以保持可讀性。

迭代器是實現__iter__()和__next__()方法的對象,生成器是簡化版的迭代器,通過yield關鍵字自動實現這些方法。 1.迭代器每次調用next()返回一個元素,無更多元素時拋出StopIteration異常。 2.生成器通過函數定義,使用yield按需生成數據,節省內存且支持無限序列。 3.處理已有集合時用迭代器,動態生成大數據或需惰性求值時用生成器,如讀取大文件時逐行加載。注意:列表等可迭代對像不是迭代器,迭代器到盡頭後需重新創建,生成器只能遍歷一次。

類方法是Python中通過@classmethod裝飾器定義的方法,其第一個參數為類本身(cls),用於訪問或修改類狀態。它可通過類或實例調用,影響的是整個類而非特定實例;例如在Person類中,show_count()方法統計創建的對像數量;定義類方法時需使用@classmethod裝飾器並將首參命名為cls,如change_var(new_value)方法可修改類變量;類方法與實例方法(self參數)、靜態方法(無自動參數)不同,適用於工廠方法、替代構造函數及管理類變量等場景;常見用途包括從

處理API認證的關鍵在於理解並正確使用認證方式。 1.APIKey是最簡單的認證方式,通常放在請求頭或URL參數中;2.BasicAuth使用用戶名和密碼進行Base64編碼傳輸,適合內部系統;3.OAuth2需先通過client_id和client_secret獲取Token,再在請求頭中帶上BearerToken;4.為應對Token過期,可封裝Token管理類自動刷新Token;總之,根據文檔選擇合適方式,並安全存儲密鑰信息是關鍵。

Python的magicmethods(或稱dunder方法)是用於定義對象行為的特殊方法,它們以雙下劃線開頭和結尾。 1.它們使對象能夠響應內置操作,如加法、比較、字符串表示等;2.常見用例包括對像初始化與表示(__init__、__repr__、__str__)、算術運算(__add__、__sub__、__mul__)及比較運算(__eq__、__lt__);3.使用時應確保其行為符合預期,例如__repr__應返回可重構對象的表達式,算術方法應返回新實例;4.應避免過度使用或以令人困惑的方

Pythonmanagesmemoryautomaticallyusingreferencecountingandagarbagecollector.Referencecountingtrackshowmanyvariablesrefertoanobject,andwhenthecountreacheszero,thememoryisfreed.However,itcannothandlecircularreferences,wheretwoobjectsrefertoeachotherbuta

Python的垃圾回收機制通過引用計數和周期性垃圾收集來自動管理內存。其核心方法是引用計數,當對象的引用數為零時立即釋放內存;但無法處理循環引用,因此引入了垃圾收集模塊(gc)來檢測並清理循環。垃圾回收通常在程序運行中引用計數減少、分配與釋放差值超過閾值或手動調用gc.collect()時觸發。用戶可通過gc.disable()關閉自動回收、gc.collect()手動執行、gc.set_threshold()調整閾值以實現控制。並非所有對像都參與循環回收,如不包含引用的對象由引用計數處理,內置
