python發郵件詳解,smtplib和email模塊詳解

在介紹具體的實現python發郵件的具體操作之前,我覺得有必要介紹下SMTP,更有助於理解python發郵件的實現原理。SMTP協議屬於TCP/IP協議簇,即簡單郵件傳輸協議,它是一組用於由源地址到目的地址傳送郵件的規則,由它來控制信件的中轉方式,python實現發郵件也是基於此基礎上進行封裝的。

1.python發郵件所需要的基礎包

python發送郵件需要用到python自帶的兩個模塊,smtplib和email。直接import導入,無需下載。
python的smtplib提供了一種很方便的途徑發送電子郵件,它對smtp協議進行了簡單的封裝。

2.smtplib的用法

smtplib用法相對來說很簡單,就是分爲兩步。

  • 創建SMTP的操作對象並連接smtp目標服務器,可以是163、QQ等
  • 根據自己的賬號登錄目標服務器(自己的郵箱地址和郵箱授權碼)
  • 調用對象中的方法,發送郵件到目標地址

python與smtp服務器之間的具體交互的通用代碼:

import smtplib
server = smtplib.SMTP(mailserver, port)  # 發件人郵箱中的SMTP服務器,端口是25
server.login(sender, passwd)  # 發件人郵箱賬號、郵箱授權碼
# msg.as_string()中as_string()是將msg(MIMEText或MIMEMultipart對象)變爲str。
server.sendmail(sender, receive, msg.as_string())  
server.quit()

具體的python連接目標服務器的代碼如下:注:本文章用的是qq的smtp服務器。
常用郵箱的smtp服務器地址:
新浪郵箱:smtp.sina.com,搜狐郵箱:smtp.sohu.com,qq郵箱:smtp.qq.com

sender_maile='[email protected]' # 發送方的郵箱地址
sender_pass = 'lsjdfsljdfk' # 郵箱提供的授權碼,可在第三方登錄,我這個是隨便打的。
sftp_obj =smtplib.SMTP('smtp.qq.com', 25)
sftp_obj.login(sender_mail, sender_pass)
#三個參數分別是:發件人郵箱賬號,收件人郵箱賬號,發送的郵件體
sftp_obj.sendmail(sender_mail, receiver_mail, msg_root.as_string())
sftp_obj.quit()
3.email模塊的詳細理解和使用

email模塊下的mime模塊下有常用的三個模塊,三個模塊中有三個大類。其實就是下邊這三個了,說的很繞,下邊爲導入方式,一目瞭然。

from email.mime.text import MIMEText    
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart    

簡單說下他們的關係,如果構造一個MIMEText對象,就表示一個文本郵件對象,如果構造一個MIMEImage對象,就表示一個作爲附件的圖片對象,要把多個對象組合起來,就用MIMEMultipart對象,他代表的是整個郵件。這樣說應該還不是很清晰,下邊就分開來說,最後會總的總結,在最後邊就是完整的代碼(可以發送一切內容的代碼)。

A.MIMEText對象中有三個需要我們設置的參數,一個是正文內容,一個是正文內容的類型,例如:”text/plain”和”text/html”,一個是正文內容的編碼。

構造普通文本:

text_info = 'hello world '
text_sub = MIMEText(text_info,'plain', 'utf-8')  

構造超文本:

url = "https://blog.csdn.net/chinesepython"
html_info = """
    <p>點擊以下鏈接,你會去向一個更大的世界</p>
    <p><a href="%s">click me</a></p>
    <p>i am very glasses for you</p>
    """ % url
html_sub = MIMEText(html_info, 'html', 'utf-8')  
# 如果不加下邊這行代碼的話,上邊的文本是不會正常顯示的,會把超文本的內容當做文本顯示
html_sub["Content-Disposition"] = 'attachment; filename="csdn.html"'

構造base64數據流,用於發送文件的時候使用,構造附件代碼:

txt_file = open(r'D:\python_files\files\hello_world.txt', 'rb').read()
txt = MIMEText(txt_file, 'base64', 'utf-8')
txt["Content-Type"] = 'application/octet-stream'
# 命名發送的附件
txt.add_header('Content-Disposition', 'attachment', filename='hello_world.txt')
B.MIMEImage對象中只需要把讀取的文件傳入就行

構造圖片:

image_file = open(r'D:\python_files\images\test.png', 'rb').read()
image = MIMEImage(image_file)
image.add_header('Content-ID', '<image1>')
# 命名發送的圖片
image["Content-Disposition"] = 'attachment; filename="red_people.png"'
C.MIMEMultipart對象創建的類型有三種,此模塊主要是通過attach方法把上邊構造的內容傳入到郵件的整體內容中。
  • 郵件類型爲”multipart/alternative”的郵件正文中包括純文本正文(text/plain)和超文本正文(text/html)。
  • 郵件類型爲”multipart/related”的郵件正文中包括圖片,聲音等內嵌資源。
  • 郵件類型爲”multipart/mixed”的郵件包含附件,圖片,文本等都可以添加,所以發的內容多的話一般是用這個的,選擇mixed類型,什麼內容都可以發。
3.郵件頭添加內容

直接上示例代碼:

from email.mime.multipart import MIMEMultipart


msg_root = MIMEMultipart('mixed')
# 發件人
msg_root['From'] = '[email protected]<[email protected]>'
# 收件人
msg_root['To'] = '[email protected]'
# 郵件主題
subject = 'python sendemail test successful'
msg_root['subject'] = Header(subject, 'utf-8')
4.特別的用法說明:

注:以下的msg_root爲:
msg_root = MIMEMultipart(‘mixed’)

msg_root.as_string()是將msg_root對象變爲str。
msg_root.attach(MIMEText或者MIMEImage對象),因爲MIMEMultipart對象代表郵件本身,其他連個是代表郵件正文,所以這個方法還是很強大的,把其他的構造內容添加到MIMEMultipart對象中就可以把文本,html,附件等一起發送了。

5.發送各種內容的具體代碼實現:

所有代碼合到一塊,發送文本,html,圖片,txt內容,用的時候你可以把需要的部分摘出來,也就是把沒有加入到msg_root的對象拿出來,直接通過下邊命令發送,例如只發送文本。
sftp_obj.sendmail(sender_mail, receiver_mail, text_sub.as_string())。

import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart


def send_email_by_qq(to):
    sender_mail = '[email protected]'
    sender_pass = 'aljflsjdf'#同樣是亂打的

    # 設置總的郵件體對象,對象類型爲mixed
    msg_root = MIMEMultipart('mixed')
    # 郵件添加的頭尾信息等
    msg_root['From'] = '[email protected]<[email protected]>'
    msg_root['To'] = to
    # 郵件的主題,顯示在接收郵件的預覽頁面
    subject = 'python sendemail test successful'
    msg_root['subject'] = Header(subject, 'utf-8')

    # 構造文本內容
    text_info = 'hello world'
    text_sub = MIMEText(text_info, 'plain', 'utf-8')
    msg_root.attach(text_sub)

    # 構造超文本
    url = "https://blog.csdn.net/chinesepython"
    html_info = """
    <p>點擊以下鏈接,你會去向一個更大的世界</p>
    <p><a href="%s">click me</a></p>
    <p>i am very galsses for you</p>
    """% url
    html_sub = MIMEText(html_info, 'html', 'utf-8')
    # 如果不加下邊這行代碼的話,上邊的文本是不會正常顯示的,會把超文本的內容當做文本顯示
    html_sub["Content-Disposition"] = 'attachment; filename="csdn.html"'   
    # 把構造的內容寫到郵件體中
    msg_root.attach(html_sub)

    # 構造圖片
    image_file = open(r'D:\python_files\images\test.png', 'rb').read()
    image = MIMEImage(image_file)
    image.add_header('Content-ID', '<image1>')
    # 如果不加下邊這行代碼的話,會在收件方方面顯示亂碼的bin文件,下載之後也不能正常打開
    image["Content-Disposition"] = 'attachment; filename="red_people.png"'
    msg_root.attach(image)

    # 構造附件
    txt_file = open(r'D:\python_files\files\hello_world.txt', 'rb').read()
    txt = MIMEText(txt_file, 'base64', 'utf-8')
    txt["Content-Type"] = 'application/octet-stream'
    #以下代碼可以重命名附件爲hello_world.txt  
    txt.add_header('Content-Disposition', 'attachment', filename='hello_world.txt')
    msg_root.attach(txt)

    try:
        sftp_obj =smtplib.SMTP('smtp.qq.com', 25)
        sftp_obj.login(sender_mail, sender_pass)
        sftp_obj.sendmail(sender_mail, to, msg_root.as_string())
        sftp_obj.quit()
        print('sendemail successful!')

    except Exception as e:
        print('sendemail failed next is the reason')
        print(e)


if __name__ == '__main__':
    # 可以是一個列表,支持多個郵件地址同時發送,測試改成自己的郵箱地址
    to = '[email protected]'
    send_email_by_qq(to)
6.總結

爲了讓不是很理解發郵件的朋友能更好的理解,在這裏是把所有的參數都寫死了,比如說發送文件的具體內容,在真正開發使用過程中,可以把具體的內容通過預留出來參數去傳入之後發送你想要發送的內容。
發郵件功能還是很實用的,在真正的開發中或者大多數場合都能用到,比如說項目中一個重要的模塊如果出問題了,你需要第一時間知道,就可以加入這個功能,把項目出問題報的具體內容發到你的郵箱,也可以第一時間想下處理的對策。
下面以我通過此程序發送的郵件內容的截圖做結尾吧。
這裏寫圖片描述

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