利用python寫郵件管理
郵件歷史。。。
-
起源
-
就是通訊的一個發展,懶得打字了省略了,以後再查吧
-
-
管理程式
-
一些讓郵件普及的郵件公司
-
郵件的工作流程
-
MUA(MailUserAgent)郵件使用者代理
-
MTA(MailTransferAgent)郵件傳輸代理
-
MDA(MailDeliveryAgent)郵件投遞代理
-
流程
-
MUT->MTA
-
qq MTA->...........................->sina MTA
-
sina MTA->.........................->sina MDA
-
sina MDA->MUA(FoxMail/outlook)郵件下載到本地電腦
-
-
編寫程式
-
傳送 MUA->MTA 協議
-
接收 MTA->MDA 協議
-
-
準備工作
-
註冊郵箱
-
第三方郵箱進行設定
-
進入設定中心
-
取得授權碼
-
案例07傳送純文字郵件‘
-
import smtplib from email.mime.text import MIMEText #MIMEText的主要引數有3個 #1。郵件內容 #2。MIME子型別,在這裡用plain代表text格式的檔案 #3.郵件的編碼格式 msg = MIMEText('這是一封文字格式的郵件','plain','utf-8') #傳送email的地址,需要更改為對應的郵件地址 from_addr = '
-
-
-
Python for mail
-
SMTP協議負責傳送郵件
-
使用Email模組構建郵件-純文字案例V07
-
HTML格式郵件傳送
-
準備HTML程式碼作為內容
-
把郵件的subtype設為html
-
傳送
-
案列V08
-
import smtplib from email.mime.text import MIMEText #MIMEText的主要的三個引數 #1。郵件內容 #2。MIME子型別的格式 這裡時HTML所以是html #3.郵件的編碼格式 msg_content = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>這是一封HTML格式的郵件</h1> </body> </html> """ #傳送郵件的地址 from_addr = '[email protected]' #傳送郵件的密碼 from_pwd = 'XXXXXXXXXXx' #收件人 to_addr = '[email protected]' #輸入SMTP伺服器地址 smtp_srv = 'smtp.qq.com' try: srv = smtplib.SMTP_SSL(smtp_srv.encode(),465) #登陸郵箱 srv.login(from_addr,from_pwd) #傳送郵件 srv.sendemail = (from_addr,[to_addr],msg_content.as_toString()) srv.quit() except Exception as e: print(e)
-
-
傳送帶附件的郵件
-
可以看作有一個文字郵件和一個附件的合體
-
需要使用MIMEltaipart格式構建
-
新增一個MIMEBase或者MEME text作為附件
-
案列V09
-
import smtplib from email.mime.text import MIMEText from email.mime.text import MIMEBase,MIMMultipart #構建基礎郵件時使用 mail_mul = MIMEMulipart() #構建郵件正文 main_text = MIMEText("這是郵件的正文",'plain','utf-8') #把構建的正文附加到郵件中 mail_mul.attach(mail_text) #構建附件,需要從本地讀入 #開啟一個本地檔案 with open('a.txt','rb') as f: s = f.read() #設定附件的MIME檔名 m = MIMEText(s,'base64','utf-8') m['Content-Type'] = 'application.octet-stream' #需要注意的 #1.attachment後的分號時英文狀態 #2.filename 後面需要英文包裹,注意外面的引號錯開 m['Content-Dispostion'] = 'attachment;filename="a.txt"' #新增MIMEMultipation mail_mul.attach(m) #傳送郵件 from_addr = '[email protected]' from_pwd = 'XXXXXXXXx' to_addr = '[email protected],com' smtp_srv = 'sntp.qq.com' try: srv = smtplib.SMTP_SSL(smtp_srv.encode(),465) #登陸郵箱 srv.load(from_addr,from_pwd) srv.sendmail(from_addr,[to_addr],mail_mul.as_string()) srv.quit() except Exception as e: print(e)
-
-
新增郵件頭,抄送等資訊
-
mail['From'] 表示傳送者的資訊,包括姓名和郵件
-
mail['To'] 表示接收者資訊,包括姓名和郵件地址
-
mail['Subject']表示摘要或者主題資訊
-
案例V10
-
-
同時支援html和text格式
-
構建一個MIMEMultipart格式的郵件
-
MIMEMultipart的subtype設定成alterbalive
-
新增html 檔案和text檔案
-
import smtplib from email.mime.text import MIMEText from email,mime.multipart import MIMEMUltipart #構建一個MIMEMultipart郵件 msg = MIMEMultapart('alternative') #構建一個HTML格式的郵件內容 html_content = """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>這是一封HTML格式的郵件</h1> </body> </html> """ msg_html = MIMEText(html_content,'html','utf-8') msg.attach(msg_html) #構建一個文字格式的郵件 msg_text = MIMEText("這是文字格式的郵件",'plain','utf-8') msg.attach(msg_text) from_addr = '[email protected]' from_pwd = 'XXXXX' to_addr = "[email protected]" smtp_srv = 'smtp.qq.com' try: srv = smtplib.SMTP_SSL(smtp_srv.encode(),465) srv.login(from_addr,from_pwd) srv_sendmail(from_addr,[to_addr],msg.as_tostring()) srv.quit() except Exception as e: print(e)
-
-
使用smtplib模組傳送郵件
-
-
POP3協議接受郵件
-
本質上講是從MDA到MTA的一個過程
-
從MDA下載下來的是一個完整的郵件結構體,需要解析才能的帶每個具有
-
步驟:
-
1.用poplib下載郵件結構體原始內容
-
1.準備相應的內容(郵件的內容,密碼。pop3例項)
-
2.身份驗證
-
3.一般會先得到郵箱內郵件的整體列表
-
4.根據相應的序號,得到某一封信的資料流
-
5.利用解析函式進行解析出相應的郵件結構體
-
-
2.emai解析郵件的具體內容
-
案例V12
-
#匯入相關的包 #poplib負責相關的MDA到MUA的下載 import poplib from email.parser import Parser from email.header import decode_header from email.utils import parseaddr #得到郵件的原始內容 #這個過程主要看負責從MDA帶MUA的下載並且使用Parse粗略的解析 def getMsg(): #準備相應的資訊 email = '[email protected]' #郵箱的授權碼 pwd = 'azyktnytwqlmbdeb' #pop3的伺服器地址 預設埠995 pop3_srv = 'pop.qq.com' #SSL代表安全通道 srv = poplib.POP3_SSL(pop3_srv) #user代表Email地址 srv.user(email) #pass_代表密碼 srv.pass_(pwd) #一下操作根據業務內容具體使用 #stat返回郵件的數量和佔用的空間 #注意stat返回一個tuple格式 msgs,counts = srv.stat() print("messages:{0},Size{1}".format(msgs,counts)) #list返回所有的郵件編號列表 #malis返回所有郵件編號列表 rsp,mails,octets = srv.list() #可以檢視返回mails列表類似 print(mails) #獲取最新一封郵件,注意,郵件的索引號從1開始,最新的郵件索引號最高 index = len(mails) #retr 負責返回一個具體索引號的一封信的內容,此內容不具有可讀性 #lines 儲存郵件的最高原始文字的每一行 rsp,lines,octets = srv.retr(index) #獲取整個郵件的原始文字 msg_count = b'\r\n'.join(lines).decode('utf8') #解析出郵件的整個結構體 #引數時解碼後的郵件整體 msg = Parser().parsestr(msg_count) #關閉連結 srv.quit() return msg # #詳細解釋得到的郵件內容 #msg表示郵件的原始內容 #idnent代表的是郵件的巢狀層級 def parseMsg(msg,indent=0): ''' 1.郵件可能是完全巢狀 2.郵件只有一個From,To,Subject之類的資訊 :param msg: :param indent: 描述郵件裡面的幾個郵件的MIMEXXX型別的內容,展示的時候進行縮排 :return: ''' #想辦法提取頭部資訊 #只有在第一層的郵件中才會有相關資訊內容 #此內容只有一個 if indent == 0: for header in ['From','To','Subject']: #使用get可以避免如果沒有相關關鍵字報錯的可能性 #如果沒有關鍵字“From"在使用msg["From"]時會報錯 value = msg.get(header,'') if value: #Subject中的內容直接解碼就可以,他是字串型別 if header == 'Subject': value = decodeStr(value) #如果是From和To欄位,則內容的大概是‘我的郵箱<[email protected]>’這種格式 else: hdr,addr = parseaddr(value) name = decodeStr(hdr) #最終的返回型別如“我的郵箱是<[email protected]>” value = "{0}<{1}>.".format(name,addr) print("{0},{1}:{2}".format(indent,header,value)) #接下來關注郵件內容本身 #郵件內容中,有可能是multipart型別,也有可能是普通郵件型別 #下面的解析使用遞迴的方法 if (msg.is_multipart()): #如果是multipart型別則呼叫遞迴解釋 #得到多部分郵件的一個基礎郵件部分 parts = msg.get_payload() #enumerate函式是內建函式 #作用是將一個列表,此處是parts,生成一個有索引和parts原內容生成的列表 #例如:enumerate(['a','b','c'])結果是:[(1,'a'),(2,'b'),(3,'c')] for n,part in enumerate(parts): #一個字串乘以一個數字的意思就是對這個字串進行n倍擴充套件 #例如("aa"*2) = 'aaaa' print("{0}spart:{1}".format(' '*indent,n)) parseMsg(part,indent+1) else:#基礎型別 #get_content_type是系統函式,得到內容的型別 content_type = msg.get_content_type() #text/plain,或者是text/html是固定值 if content_type == 'text/plain' or content_type == 'text/html': content = msg.get_payload(decode=True) charset = gussCharset(msg) if charset: content = content.decode(charset) print("{0}text:{1}".format(indent,content)) else:#不是文字內容,因該是附件 print('{0}Attachment:{1}'.format(indent,content_type)) def decodeStr(s): ''' s代表一封郵件中的from,to,Subject中的任意一項 對s進行解碼,解碼是通過編碼的逆過程 :param s: :return: ''' value,charset = decode_header(s)[0] #charset完全可能為空 if charset: #如果指定編碼,則用指定的編碼格式進行解碼 value = value.decode(charset) return value def gussCharset(msg): ''' 猜測郵件的編碼格式 :param msg: :return: ''' #呼叫現成的函式 charset = msg.get_charset() if charset is None: #找到相應的內容型別轉換成小寫 content_type = msg.get("Content-Type","").lower() pos = content_type.find('charset=') if pos > 0: #如果包含charset,則內容為charset=XXX charset = content_type[pos+8:].strip() return charset if __name__ == '__main__': #得到郵件的原始內容 msg = getMsg() print(msg) #精確解析郵件的內容 parseMsg(msg,0)
-
-
-
-