python email模塊


python email模塊

 

官方文檔

 

email模塊

電子郵件包是一個用於管理電子郵件消息的庫。它的特殊設計不用於向SMTP (RFC 2821)、NNTP或其他服務器發送任何電子郵件消息;這些是模塊的函數,如smtplib和nntplib。電子郵件包嘗試盡可能符合RFC,支持RFC 5233和RFC 6532,以及與mime相關的RFC 2045、RFC 2046、RFC 2047、RFC 2183和RFC 2231。

 

電子郵件包的總體結構可以分為三個主要組件,以及控制其他組件行為的第四個組件。

 

包的核心組件是表示電子郵件消息的“對象模型”。應用程序主要通過消息子模塊中定義的對象模型接口與包進行交互。應用程序可以使用這個API詢問關於現有電子郵件的問題,構造新的電子郵件,或者添加或刪除本身使用相同對象模型接口的電子郵件子組件。也就是說,根據電子郵件消息及其MIME子組件的性質,電子郵件對象模型是所有提供EmailMessage API的對象的樹結構。

 

包的另外兩個主要組件是解析器和生成器。解析器獲取電子郵件消息的序列化版本(字節流),並將其轉換為EmailMessage對象樹。生成器接收電子郵件消息並將其轉換回序列化的字節流。(解析器和生成器也處理文本字符流,但不建議使用這種用法,因為很容易出現以某種方式無效的消息。)

 

控制組件是策略模塊。每個電子郵件消息、每個生成器和每個解析器都有一個關聯的策略對象來控制其行為。通常,應用程序只需要在創建EmailMessage時指定策略,方法是直接實例化EmailMessage來創建新電子郵件,或者使用解析器解析輸入流。但是,當使用生成器序列化消息時,策略可以更改。例如,這允許從磁盤解析一般的電子郵件消息,但是在將其發送到電子郵件服務器時,可以使用標准SMTP設置對其進行序列化。

 

電子郵件包盡力向應用程序隱藏各種治理rfc的詳細信息。從概念上講,應用程序應該能夠將電子郵件消息視為unicode文本和二進制附件的結構化樹,而不必擔心這些附件在序列化時是如何表示的。然而,在實踐中,經常需要了解至少一些管理MIME消息及其結構的規則,特別是MIME“內容類型”的名稱和性質,以及它們如何標識多部分文檔。在大多數情況下,這些知識只應該在更復雜的應用程序中使用,即使在這種情況下,也應該只是高級結構,而不是那些結構如何表示的細節。由於MIME內容類型在現代互聯網軟件中被廣泛使用(不僅僅是電子郵件),這對許多程序員來說將是一個熟悉的概念。

 

以下部分描述了電子郵件包的功能。我們從消息對象模型開始,它是應用程序將使用的主要接口,然后是解析器和生成器組件。然后介紹策略控制,它完成了對庫的主要組件的處理。

接下來的三個部分將討論包可能引發的異常和解析器可能檢測到的缺陷(不符合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對象
電子郵件。標題:國際化頭
電子郵件。字符集:表示字符集
電子郵件。編碼器:編碼器
電子郵件。跑龍套:其他工具
電子郵件。迭代器:迭代器

 

Email模塊

如果想在郵件中攜帶附件、使用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連接,它支持所有的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()

 

 

爬取天氣預報並發到指定人的QQ郵箱(使用新浪郵箱)

天氣預報: 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℃持續無風向 |
+-------------+------------+------------------+

 

 

 

 

 

 

參考:https://www.linuxidc.com/Linux/2017-12/149258.htm

參考:https://www.jb51.net/article/49219.htm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM