利用python寫郵件發送模塊

Email

郵件歷史。。。

  • 起源

    • 就是通信的一個發展,懶得打字了省略了,以後再查吧

  • 管理程序

    • 一些讓郵件普及的郵件公司

郵件的工作流程

  • 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 = '[email protected]'
        #授權密碼,大多數的郵箱在使用第三方軟件時,都需要驗證密鑰,這裏不是指郵箱的密碼
        from_pwd = 'XXXXXXXXXXX'
        #收件人
        to_addr = '[email protected]'
        
        #輸入smtplib服務器地址
        #此處根據不同的郵件服務商有不同的值
        #現在基本任何一家郵件服務商在開啓第三方郵件的時候都需要開啓服務
        #TX QQ郵箱的smtplib地址時smtplib.qq.com
        smtp_srv = 'smtplib.qq.com'
        
        try:
            srv = smtplib.SNTP_SSL(smtp_srv.encode(),465) #這裏的465時QQ郵箱的端口
            #登陸郵箱,任何的郵箱在使用之前都必須的登陸
            srv.login(from_addr,from_pwd)
            #發送郵件
            #三參數,發送地址,接受的地址(必須時list格式),發送內容時字符串格式
            srv.sendmail(from_addr,[to_addr],msg.as_String())
            srv.quit()
        except Exception as e:
            print(e)
        

         

  • 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 = 'XXXXXXX@qq,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)

             

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