Python 3 郵件的接收(IMAP)

因爲前段時間在使用Ubuntu的時候,不想在GUI下接收郵件所以就打算自己寫一個在命令行下接收郵件的程序,考慮到開發效率問題所以就直接用Python來寫了。
(開發環境是Python3 + Ubuntu16.04 + IMAP協議)
參考資料:
python3 imaplib庫的官方文檔
python3 email庫的官方文檔


郵件協議

在開始之前下面我們來認識一下郵件協議(POP3,IMAP,SMTP)

協議 功能
POP3 主要用於客戶端遠程管理服務器上的郵件
IMAP 交互式郵件訪問協議
SMTP 簡單郵件傳輸協議

下面就簡單的來說一下各協議的區別,協議的詳細內容可以自行查看網絡資料,和相關書籍

POP3

POP3協議是Post Office Protocol 3的簡稱,即郵局協議的第3個版本,是TCP/IP協議族中的一員(默認端口是110)。本協議主要用於支持使用客戶端遠程管理在服務器上的電子郵件。

IMAP

IMAP全稱是Internet Mail Access Protocol,即交互式郵件訪問協議,是一個應用層協議(端口是143)。用來從本地郵件客戶端(Outlook Express、Foxmail、Mozilla Thunderbird等)訪問遠程服務器上的郵件。

SMTP

SMTP的全稱是“Simple Mail Transfer Protocol”,即簡單郵件傳輸協議(25號端口)。它是一組用於從源地址到目的地址傳輸郵件的規範,通過它來控制郵件的中轉方式。SMTP 協議屬於 TCP/IP 協議簇,它幫助每臺計算機在發送或中轉信件時找到下一個目的地。我們知道SMTP協議簡單來說就是一個郵件發送的傳輸協議(不提供郵件接收功能),而POP3和IMAP這兩個協議是郵件的接收(下載)協議。那麼POP3和IMAP的區別是什麼呢?

POP3和IMAP協議的區別

下面就來說一說這兩個協議的主要區別。
雖然這兩個協議都是從郵件服務器那裏下載郵件到本地的協議,但是不同的是IMAP提供跟郵件服務器的雙向通信,也即在客戶端所作的更改會反饋給服務器端,跟服務器端形成同步(例如刪除郵件,創建文件夾等等的操作)。而POP3是單向通信的,即下載郵件到本地就算了,所作的更改都只是在客戶端,不會反映到服務器端。所以使用IMAP協議也會更便捷,體驗更好,更可靠。


用Python3開發

因爲我本身的開發環境的問題,所以就直接採用python進行開發。

登陸郵箱

用python來開發郵件接收程序非常的簡單,主要還是用兩個自帶的庫就可以了,imaplib庫和email庫。一開始先用import把兩個庫導入進來。

import imaplib
import email  #導入兩個庫

conn = imaplib.IMAP4_SSL(port = '***',host = '***')
print('已連接服務器')
conn.login('***@outlook.com','password')
print('已登陸')

上面的代碼中port和host可以在網頁上登陸服務器然後在郵箱設置裏面就能看到郵箱提供的IMAP協議的域名跟端口了。conn.login('賬號','密碼')用來登陸郵箱(使用平時登陸的賬號密碼)。完成這兩步連接並登陸上郵箱後,就可以進行下一步的相關操作了。

下載郵件

在下載郵件之前我們必須先選擇郵箱中的一個文件夾
conn.select()
查看官方文檔可以知道這個函數的默認值是’INBOX’,如果之前自己沒有改過郵箱的收件夾,一般默認就是INBOX,不用在函數裏面填寫其他參數。
選完文件夾後使用
type, data = conet.search(None, 'ALL')
搜索匹配的郵件,第一個參數是字符集,None默認就是ASCII編碼,第二個參數是查詢條件,這裏的ALL就是查找全部。該函數返回的是字符數組,我們只需要數組的第一個元素,數組的第一個元素是郵件的編號,並且按接收時間按升序排序並且中間用空格隔開。例如[‘1 2 3 4 5 6 7 8 9 10 ……’],所以現在我們只需把這些用空格隔開的數分離開來放到一個新的數組就OK了,newlist=data[0].split()
然後可以調用fetch()方法來取回郵件,不過取回來的郵件是一堆亂七八糟不知道什麼鬼的東西,我們要把我們取回的郵件用email庫來進行一些處理。

#如果我們要取回第一封郵件可以把newlist[0]傳遞給fetch()

type, data = conet.fetch(newlist[0], '(RFC822)')

msg = email.message_from_string(data[0][1].decode('utf-8')) 

#用utf-8解碼,否側會報錯

這樣我們就把取回來的亂七八糟的東西交給了email庫來處理,接下來我們只需要操作email庫就好了。

解析郵件

我們把解析的任務交給email庫來處理。
我們現在就可以用email庫來從郵件中提取出我們需要的信息了,例如標題,郵件的日期,等等有用的信息。
要提取出標題信息我們可以用get()

 sub = msg.get('subject')

 #用get()獲取標題並進行初步的解碼。

 subdecode = email.header.decode_header(a)[0][0]

  #打印標題
 print(subdecode.decode('utf-8'))

其他的標頭信息都可以通過get()來獲得。

下面來獲取信體部分

 for part in msg.walk():
        # 如果ture的話內容是沒用的
        if not part.is_multipart():            
            print(part.get_payload(decode=True).decode('utf-8')) 
            # 解碼出文本內容,直接輸出來就可以了。

walk()函數能歷遍郵件所有部分,所以通常都把它放到for循環裏面使用。然後再使用is_multipart()函數來判斷內容是否有用,打印出有用內容最後用get_payload(decode=True).decode('utf-8')解碼並且打印到控制檯。通常這個循環有兩次,第一次是單純的字符串格式的,能在控制檯顯示出來的,第二次循環打印的是像HTML的格式,能在瀏覽器裏查看,就像平時看到的郵件那樣。


好了,郵件的接收就說到這裏了。更多的詳細情況可以自己去我在開頭給的兩個連接裏面查看。有什麼錯誤也可以在下面給我留言。


個人公衆號
喜歡可以加我的個人公衆號,掃上面的二維碼,或者搜索微信公衆號“科學技術工作室”
我會發一些有趣的科學技術文章,喜歡的朋友可以加一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章