官方文檔html
電子郵件包是一個用於管理電子郵件消息的庫。它的特殊設計不用於向SMTP (RFC 2821)、NNTP或其餘服務器發送任何電子郵件消息;這些是模塊的函數,如smtplib和nntplib。電子郵件包嘗試儘量符合RFC,支持RFC 5233和RFC 6532,以及與mime相關的RFC 204五、RFC 204六、RFC 204七、RFC 2183和RFC 2231。python
電子郵件包的整體結構能夠分爲三個主要組件,以及控制其餘組件行爲的第四個組件。linux
包的核心組件是表示電子郵件消息的「對象模型」。應用程序主要經過消息子模塊中定義的對象模型接口與包進行交互。應用程序可使用這個API詢問關於現有電子郵件的問題,構造新的電子郵件,或者添加或刪除自己使用相同對象模型接口的電子郵件子組件。也就是說,根據電子郵件消息及其MIME子組件的性質,電子郵件對象模型是全部提供EmailMessage API的對象的樹結構。程序員
包的另外兩個主要組件是解析器和生成器。解析器獲取電子郵件消息的序列化版本(字節流),並將其轉換爲EmailMessage對象樹。生成器接收電子郵件消息並將其轉換回序列化的字節流。(解析器和生成器也處理文本字符流,但不建議使用這種用法,由於很容易出現以某種方式無效的消息。)api
控制組件是策略模塊。每一個電子郵件消息、每一個生成器和每一個解析器都有一個關聯的策略對象來控制其行爲。一般,應用程序只須要在建立EmailMessage時指定策略,方法是直接實例化EmailMessage來建立新電子郵件,或者使用解析器解析輸入流。可是,當使用生成器序列化消息時,策略能夠更改。例如,這容許從磁盤解析通常的電子郵件消息,可是在將其發送到電子郵件服務器時,可使用標準SMTP設置對其進行序列化。服務器
電子郵件包盡力嚮應用程序隱藏各類治理rfc的詳細信息。從概念上講,應用程序應該可以將電子郵件消息視爲unicode文本和二進制附件的結構化樹,而沒必要擔憂這些附件在序列化時是如何表示的。然而,在實踐中,常常須要了解至少一些管理MIME消息及其結構的規則,特別是MIME「內容類型」的名稱和性質,以及它們如何標識多部分文檔。在大多數狀況下,這些知識只應該在更復雜的應用程序中使用,即便在這種狀況下,也應該只是高級結構,而不是那些結構如何表示的細節。因爲MIME內容類型在現代互聯網軟件中被普遍使用(不只僅是電子郵件),這對許多程序員來講將是一個熟悉的概念。併發
如下部分描述了電子郵件包的功能。咱們從消息對象模型開始,它是應用程序將使用的主要接口,而後是解析器和生成器組件。而後介紹策略控制,它完成了對庫的主要組件的處理。app
接下來的三個部分將討論包可能引起的異常和解析器可能檢測到的缺陷(不符合rfc)。而後,咱們將介紹headerregistry和contentmanager子組件,它們分別爲更詳細地操做頭部和有效負載提供了工具。這兩個組件都包含與消費和生成非平凡消息相關的特性,並且還記錄了它們的可擴展性api,這將是高級應用程序感興趣的。函數
下面是一組使用前面幾節中介紹的api的基本部分的示例。工具
上面所示的是電子郵件包的現代(unicode友好)API。餘下的部分,從Message類開始,將介紹遺留的compat32 API,它更直接地處理如何表示電子郵件消息的細節。compat32 API不會嚮應用程序隱藏rfc的細節,可是對於須要在該級別上操做的應用程序,它們多是有用的工具。因爲向後兼容性的緣由,本文檔還適用於仍然使用compat32 API的應用程序。
在3.6版更改:文檔重組和重寫,促進新的EmailMessage / EmailPolicy API。
Contents of the email
package documentation:
Legacy API:
電子郵件包文檔內容:
電子郵件。消息:表示電子郵件消息
電子郵件。解析器:解析電子郵件消息
實現FeedParser API
解析器API
額外的筆記
電子郵件。生成器:生成MIME文檔
電子郵件。策略:策略對象
電子郵件。錯誤:異常和缺陷類
電子郵件。headerregistry:自定義頭對象
電子郵件。contentmanager:管理MIME內容
Content Manager實例
電子郵件:示例
遺留API:
email.message。消息:使用compat32 API表示電子郵件消息
電子郵件。mime:從零開始建立電子郵件和mime對象
電子郵件。標題:國際化頭
電子郵件。字符集:表示字符集
電子郵件。編碼器:編碼器
電子郵件。跑龍套:其餘工具
電子郵件。迭代器:迭代器
若是想在郵件中攜帶附件、使用html書寫郵件,附帶圖片等等,就須要使用email模塊及其子模塊。下面來看看email包,email包是用來管理email信息的,它包括MIME和其餘基於RFC 2822的消息格式。email包的主要特徵是在它內部解析和生成email信息是分開的模塊來實現的。
MIME消息由消息頭和消息體兩大部分組成,在郵件裏就是郵件頭和郵件體。郵件頭與郵件體之間以空行進行分隔。
郵件頭包含了發件人、收件人、主題、時間、MIME版本、郵件內容的類型等重要信息。每條信息稱爲一個域,由域名後加「: 」和信息內容構成,能夠是一行,較長的也能夠佔用多行。域的首行必須「頂頭」寫,即左邊不能有空白字符(空格和製表符);續行則必須以空白字符打頭,且第一個空白字符不是信息自己固有的。
郵件體包含郵件的內容,它的類型由郵件頭的「Content-Type」域指出。最多見的類型有text/plain(純文本)和text/html(超文本)。郵件體被分爲多個段,每一個段又包含段頭和段體兩部分,這兩部分之間也以空行分隔。常見的multipart類型有三種:multipart/mixed, multipart/related和multipart/alternative。
在email的包裏面包含了不少模塊:
email.message
email.parser
email.generator
email.mime 建立email和MIME對象
email.header
email.charset
email.encoders
email.ereors
email.utils
email.iterators
主要來看看email.mime,在郵件中攜帶附件、圖片、音頻時,主要使用的是該模塊。通常狀況下,你經過解析一個文件或者一段text來生成一個消息對象結構,你也能夠從頭開始創建一個消息結構,實際上,你能夠給一個已經存在的消息結構追加一個新的消息對象。你能夠經過建立message實例來建立一個對象結構,而後給該結構追加附件和頭部信息。email包提供了一些子類使得該操做變得很容易。
模擬在郵件內容中攜帶圖片,以下:
郵件內容中攜帶圖片
from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.image import MIMEImage import smtplib from_mail = 'froooooooom@gmail.com' to_mail = 'toooooooooo@qq.com' msg = MIMEMultipart() msg['From'] = from_mail msg['To'] = to_mail msg['Subject'] = 'python mail test' body = 'test img send' con = MIMEText('<b>%s</b> <img alt="" src="cid:D:\\10535-102.jpg" /> ' % body,'html') msg.attach(con) img = MIMEImage(file('D:\\10535-102.jpg','rb').read()) img.add_header('Content-ID','D:\\10535-102.jpg') msg.attach(img) server = smtplib.SMTP('smtp.gmail.com') server.docmd('ehol','tooooooo@gmail.com') server.starttls() server.login('username@gmail.com','password') server.sendmail(from_mail,to_mail,msg.as_string()) server.quit()
郵件中攜帶附件
發送帶附件的郵件,首先要建立MIMEMultipart()實例,而後構造附件,若是有多個附件,可依次構造,最後利用smtplib.smtp發送
模擬在 郵件中攜帶附件 ,以下:
from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart import smtplib #建立一個帶附件的實例 msg = MIMEMultipart() txt = MIMEText("這是中文的郵件內容哦",'plain','gb2312') msg.attach(txt) #構造附件1 att1 = MIMEText(open('d:\\drcom.rar', 'rb').read(), 'base64', 'gb2312') att1["Content-Type"] = 'application/octet-stream' att1["Content-Disposition"] = 'attachment; filename="drcom.rar"'#這裏的filename能夠任意寫,寫什麼名字,郵件中顯示什麼名字 msg.attach(att1) #構造附件2 att2 = MIMEText(open('d:\\123.txt', 'rb').read(), 'base64', 'gb2312') att2["Content-Type"] = 'application/octet-stream' att2["Content-Disposition"] = 'attachment; filename="123.txt"' msg.attach(att2) #加郵件頭 msg['to'] = 'tooooooo@qq.com' msg['from'] = 'frommmmmmm@gmail.com' msg['subject'] = 'hello world' #發送郵件 try: server = smtplib.SMTP() server.connect('smtp.gmail.com') server.starttls() server.login('xxxxx@gmail.com','xxxxxxxxx')#XXX爲用戶名,XXXXX爲密碼 server.sendmail(msg['from'], msg['to'],msg.as_string()) server.quit() print '發送成功' except Exception, e: print str(e)
smtp實例封裝一個smtp鏈接,它支持全部的SMTP和ESMTP操做指令,若是host和port參數被定義,則smtp會在初始化期間自動調用connect()方法,若是connect()方法失敗,則會觸發SMTPConnectError異常,timeout參數設置了超時時間。
SMTP模塊的方法:
SMTP.set_debuglevel(level)
設置輸出debug調試信息,默認不輸出調試信息。
SMTP.docmd(cmd[, argstring])
發送一個command到smtp服務器,
SMTP.connect([host[, port]])
鏈接到指定的smtp服務器,默認是本機的25端口。也能夠寫成hostname:port的形式。
SMTP.helo([hostname])
使用helo指令向smtp服務器確認你的身份。
SMTP.ehlo([hostname])
使用ehlo指令向esmtp服務器確認你的身份。
SMTP.ehlo_or_helo_if_needed()
若是在之前的會話鏈接中沒有提供ehlo或者helo指令,這個方法調用ehlo()或者helo()。
SMTP.has_extn(name)
判斷指定的名稱是否在smtp服務器上。
SMTP.verify(address)
判斷郵件地址是否在smtp服務器上存在。
SMTP.login(user, password)
登錄須要驗證的smtp服務器,若是以前沒有提供ehlo或者helo指令,則會先嚐試ESMTP的ehlo指令。
SMTP.starttls([keyfile[, certfile]])
使smtp鏈接運行在TLS模式,全部的smtp指令都會被加密。
SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])
發送郵件,該方法須要一些郵件地址和消息。
SMTP.quit()
終止smtp會話而且關閉鏈接。
1.注意:本人測試使用新浪郵箱:
# 新浪免費郵箱發信(smtp) # 服務器的地址爲:smtp.sina.com # 默認端口是25 # # 新浪免費郵箱收信(pop3) # 服務器的地址爲:pop.sina.com # 默認端口是110
2.若是大家使新浪郵箱必定要開啓POP3/SMTP服務:
3.另外注意:本人登錄使用的是用戶名密碼,可是如網易郵箱,登錄須要受權碼!
使用sendmail發送郵件得測試代碼
#coding: utf-8 import smtplib from email.mime.text import MIMEText from email.header import Header #收件人和發件人 receiver = '188xxxx7275@163.com' sender = '83xxxx202@qq.com' #發件人郵箱的SMTP服務器(即sender的SMTP服務器) smtpserver = 'smtp.qq.com' #發件人郵箱的用戶名和受權碼(不是登錄郵箱的密碼) username = '83xxxx202@qq.com' password = 'moxxxxxxxxxxxfcd' #(83xxxx202@qq.com郵箱的受權碼或者密碼) mail_title = '有陌生人來訪!' mail_body = '請查看附件圖片' #建立一個實例 message = MIMEText( mail_body, 'plain', 'utf-8' ) #郵件正文 # (plain表示mail_body的內容直接顯示,也能夠用text,則mail_body的內容在正文中以文本的形式顯示,須要下載) message ['From'] = sender #郵件上顯示的發件人 message['To'] = receiver #郵件上顯示的收件人 message['Subject'] = Header( mail_title, 'utf-8' ) #郵件主題 smtp = smtplib.SMTP() #建立一個鏈接 smtp.connect( smtpserver ) #鏈接發送郵件的服務器 smtp.login( username, password ) #登陸服務器 smtp.sendmail( sender, receiver, message.as_string() ) #填入郵件的相關信息併發送 smtp.quit()
天氣預報: https://tianqi.so.com/weather/
# coding: utf-8 import smtplib from email.mime.text import MIMEText from email.header import Header import requests from bs4 import BeautifulSoup import prettytable as pt def get_Data(url): data_list = [] response = requests.get(url) html_doc = response.text soup = BeautifulSoup(html_doc, 'lxml') # 將html代碼自動補全,並按html代碼格式返回 wendu = soup.find('div', class_='temperature').get_text() tianqi = soup.find('div', class_='weather-icon-wrap').get_text() data_list.append("如今的溫度:%s\n如今天氣狀況:%s" % (wendu, tianqi)) list = soup.find_all('ul', class_='weather-columns') for item in list: data_list.append(item.get_text()) print("列表數據:",data_list) a = 1 tb = pt.PrettyTable() #建立PrettyTable對象 tb.field_names = ["日期","天氣","詳情"] for item in data_list: # print(a) if a != 1: # print(item.strip()) # print(item.strip().split()[0]+item.strip().split()[1],item.strip().split()[2],item.strip().split()[3]) tb.add_row([item.strip().split()[0]+item.strip().split()[1],item.strip().split()[2],item.strip().split()[3]]) else: print(item.strip()) a+=1 print(tb) return tb def send_mail(msg,receiver): # 收件人 receiver = receiver mail_title = '天氣預報' mail_body = str(msg) # 建立一個實例 message = MIMEText(mail_body, 'plain', 'utf-8') # 郵件正文 # (plain表示mail_body的內容直接顯示,也能夠用text,則mail_body的內容在正文中以文本的形式顯示,須要下載) message['From'] = sender # 郵件上顯示的發件人 message['To'] = receiver # 郵件上顯示的收件人 message['Subject'] = Header(mail_title, 'utf-8') # 郵件主題 smtp = smtplib.SMTP() # 建立一個鏈接 smtp.connect(smtpserver) # 鏈接發送郵件的服務器 smtp.login(username, password) # 登陸服務器 smtp.sendmail(sender, receiver, message.as_string()) # 填入郵件的相關信息併發送 smtp.quit() if __name__ == '__main__': sender = '發送者郵箱' # 發件人郵箱的SMTP服務器(即sender的SMTP服務器) smtpserver = 'smtp.sina.com' # 發件人郵箱的用戶名和受權碼(不是登錄郵箱的密碼) username = '發送者登錄郵箱' password = '密碼' # (83xxxx202@qq.com郵箱的受權碼或者密碼) url_list = ['url1','url2'] receiver_list =['接收者郵箱1','接收者郵箱2'] for i in range(len(url_list)): tb = get_Data(url_list[i]) #得到每個用戶的數據 send_mail(tb,receiver_list[i]) #發送郵件
列表數據: ['如今的溫度:19\n如今天氣狀況:晴', '今天 (05-13) 多雲\n 16/24℃輕度北風 3-5級', '明天 (05-14) 小雨轉中雨\n 18/24℃良東南風 微風', '週三 (05-15) 小雨轉多雲\n 19/26℃優北風 微風', '週四 (05-16) 多雲\n 20/30℃優東北風 微風', '週五 (05-17) 多雲\n 20/29℃良東風 微風', '週六 (05-18) 小雨\n 19/31℃優東風 微風', '週日 (05-19) 小雨轉多雲\n 12/27℃優北風 5-6級'] 如今的溫度:19 如今天氣狀況:晴 +-------------+------------+----------------+ | 日期 | 天氣 | 詳情 | +-------------+------------+----------------+ | 今天(05-13) | 多雲 | 16/24℃輕度北風 | | 明天(05-14) | 小雨轉中雨 | 18/24℃良東南風 | | 週三(05-15) | 小雨轉多雲 | 19/26℃優北風 | | 週四(05-16) | 多雲 | 20/30℃優東北風 | | 週五(05-17) | 多雲 | 20/29℃良東風 | | 週六(05-18) | 小雨 | 19/31℃優東風 | | 週日(05-19) | 小雨轉多雲 | 12/27℃優北風 | +-------------+------------+----------------+ 列表數據: ['如今的溫度:21\n如今天氣狀況:多雲', '今天 (05-13) 晴轉小雨\n 17/25℃持續無風向 微風', '明天 (05-14) 多雲轉小雨\n 17/25℃持續無風向 微風', '週三 (05-15) 小雨轉晴\n 19/28℃持續無風向 微風', '週四 (05-16) 晴轉小雨\n 20/28℃持續無風向 微風', '週五 (05-17) 多雲轉陰\n 21/28℃持續無風向 微風', '週六 (05-18) 陣雨\n 18/28℃持續無風向 微風', '週日 (05-19) 多雲\n 17/27℃持續無風向 微風'] 如今的溫度:21 如今天氣狀況:多雲 +-------------+------------+------------------+ | 日期 | 天氣 | 詳情 | +-------------+------------+------------------+ | 今天(05-13) | 晴轉小雨 | 17/25℃持續無風向 | | 明天(05-14) | 多雲轉小雨 | 17/25℃持續無風向 | | 週三(05-15) | 小雨轉晴 | 19/28℃持續無風向 | | 週四(05-16) | 晴轉小雨 | 20/28℃持續無風向 | | 週五(05-17) | 多雲轉陰 | 21/28℃持續無風向 | | 週六(05-18) | 陣雨 | 18/28℃持續無風向 | | 週日(05-19) | 多雲 | 17/27℃持續無風向 | +-------------+------------+------------------+