POP3和IMAP是郵件相關(guān)的協(xié)議,IMAP是比POP3更高級一點的協(xié)議萧吠,實現(xiàn)了了客戶端和服務(wù)端的交互左冬;郵件協(xié)議在實際工作中的應(yīng)用較為廣泛。
POP3
它是因特網(wǎng)電子郵件的第一個離線協(xié)議標(biāo)準(zhǔn),POP3允許用戶從服務(wù)器上把郵件存儲到本地主機(即自己的計算機)上,POP3協(xié)議允許電子郵件客戶端下載服務(wù)器上的郵件纸型,但是在客戶端的操作(如移動郵件、標(biāo)記已讀等),不會反饋到服務(wù)器上
SMTP
SMTP 的全稱是“Simple Mail Transfer Protocol”狰腌,即簡單郵件傳輸協(xié)議除破。它是一組用于從源地址到目的地址傳輸郵件的規(guī)范,通過它來控制郵件的中轉(zhuǎn)方式琼腔。SMTP 協(xié)議屬于 TCP/IP 協(xié)議簇瑰枫,它幫助每臺計算機在發(fā)送或中轉(zhuǎn)信件時找到下一個目的地。SMTP 服務(wù)器就是遵循 SMTP 協(xié)議的發(fā)送郵件服務(wù)器丹莲。
SMTP 認(rèn)證光坝,簡單地說就是要求必須在提供了賬戶名和密碼之后才可以登錄 SMTP 服務(wù)器,這就使得那些垃圾郵件的散播者無可乘之機甥材。
增加 SMTP 認(rèn)證的目的是為了使用戶避免受到垃圾郵件的侵?jǐn)_盯另。
IMAP
IMAP全稱是Internet Mail Access Protocol,即交互式郵件存取協(xié)議洲赵,它是跟POP3類似郵件訪問標(biāo)準(zhǔn)協(xié)議之一鸳惯。不同的是,開啟了IMAP后叠萍,您在電子郵件客戶端收取的郵件仍然保留在服務(wù)器上芝发,同時在客戶端上的操作都會反饋到服務(wù)器上,如:刪除郵件苛谷,標(biāo)記已讀等辅鲸,服務(wù)器上的郵件也會做相應(yīng)的動作。
在python中支持POP3協(xié)議腹殿,也支持IMAP協(xié)議独悴,但是IMAP因為其交互性逐漸取代了POP3成為了郵件服務(wù)器與客戶端的交互,下面主要使用IMAP協(xié)議來獲取郵件正文赫蛇、附件绵患、移動或刪除郵件。
import re
import email
from imapclient import IMAPClient
import traceback
class **EmailRead**(object):
"""實現(xiàn)讀取郵件正文悟耘、讀取附件功能落蝙、移動郵件、刪除郵件"""
def **__init__**(self, user, passwd, index_file, re_list, server_adderss, port, move_file=None):
"""
:param user: 登陸用戶名
:param passwd: 登陸密碼
:param index_file: 需要查詢的郵件文件夾
:param re_list: 需要查找的郵件主題滿足的正則表達(dá)式
:param move_file: 將郵件移動到該文件夾
:param server_adderss: 郵件服務(wù)器地址
:param port: 郵件服務(wù)器IMAP協(xié)議端口
"""
self.server_address = server_adderss
self.user = user
self.password = passwd
self.index_file = index_file
self.move_file = move_file
self.re_list = re_list
self.server = None
self.port = port
self.item = None
self.file_type_list = ['image/jpeg', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
def **reade_email**(self):
"""
查找郵件并根據(jù)附件類型下載附件
:return:
"""
self.server = IMAPClient(self.server_address, port=993, ssl=True)
self.server.login(self.user, self.password)
self.server.select_folder(self.index_file, readonly=False)
result = self.server.search(['all']) # 獲取所有郵件
if result:
self.messages = self.server.fetch(result, ['BODY.PEEK[]'])
for message_id, message in self.messages.items():
e = email.message_from_string(message[b'BODY[]'].decode())
# 生成Message類型 e
try:
subject = str(email.header.make_header(
email.header.decode_header(e['SUBJECT']))) # 解碼subject
except:
subject = e['SUBJECT']
"""正則匹配標(biāo)題中的 MSO """
if self.subject_re(subject):
"""獲取附件和正文"""
for part in e.walk():
filename = part.get_filename()
content_type = part.get_content_type()
con = part.get_payload(decode=False)
if not filename and content_type == 'text/html':
if isinstance(con, bytes):
con = part.get_payload(decode=True).decode()
elif filename and content_type in self.file_type_list:
con = part.get_payload(decode=True)
with open(filename, 'wb') as f:
f.write(con)
f.close()
else:
# list返回附件對象作用類似于e
pass
def **move_email**(self, *id):
"""郵件移動和刪除功能:傳入的move_file是None則不移動只刪除"""
messages = self.server.fetch(list(id), ['BODY.PEEK[]'])
if None!= self.move_file:
self.server.copy(messages, self.move_file) # move
self.server.delete_messages(messages) # delete
self.server.expunge() # save delete
def **subject_re**(self, subject):
"""用于匹配主題正則表達(dá)式"""
for i in self.re_list:
mso_re = re.search(i, subject)
if mso_re:
return True
else:
pass
return False
def**close**(self):
self.server.logout()
該系統(tǒng)也可以用于解決部分郵件驗證的暂幼,可以直接從郵件獲取到驗證碼的正文筏勒,并進(jìn)一步提取。