Python 第三方模塊之 smtplib

一、python對SMTP的支持

SMTP(Simple Mail Transfer Protocol)是簡單傳輸協議,它是一組用於用於由源地址到目的地址的郵件傳輸規則。

python中對SMTP進行了簡單的封裝,可以發送純文本郵件、HTML郵件以及帶附件的郵件。兩個核心模塊如下:

  • email模塊:負責構建郵件
  • smtplib模塊:負責發送郵件

python創建SMTP對象語法如下:

import smtplib
smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
# 或者
smtpObj = smtplib.SMTP_SSL( [host [, port [, local_hostname]]] )

參數說明:
    host: SMTP 服務器主機。 你可以指定主機的ip地址或者域名如: runoob.com,這個是可選參數。
    port: 如果你提供了 host 參數, 你需要指定 SMTP 服務使用的端口號,一般情況下 SMTP 端口號爲25。
    local_hostname: 如果 SMTP 在你的本機上,你只需要指定服務器地址爲 localhost 即可。 

python SMTP對象使用sendmail方法發送郵件,語法如下:

SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])
參數說明:
    from_addr: 郵件發送者地址。
    to_addrs: 字符串列表,郵件發送地址。
    msg: 發送消息 

這裏要注意一下第三個參數,msg 是字符串,表示郵件。我們知道郵件一般由標題,發信人,收件人,郵件內容,附件等構成,發送郵件的時候,要注意 msg 的格式。這個格式就是 smtp 協議中定義的格式。

email模塊:支持發送的郵件內容爲純文本,HTML內容,圖片,附件。email模塊中有幾類來針對不同的郵件內容形式,常用如下:

  • MIMEText : (MIME媒體類型)內容形式爲純文本,HTML頁面(導入方式 : from email.mime.text import MIMEText)
  • MIMEImage : 內容形式爲圖片(導入方式 : from email.mime.image import MIMEImage)
  • MIMEMultupart : 多形式組合,可包含文本和附件(導入方式 : from email.mime.multipart import MIMEMultipart)

.MIMEText語法:

MIMEText(msg,type,chartset)
    msg:文本內容
    type:文本類型默認爲plain(純文本)#發送HTML格式的時候,修改爲html,但同時要求msg的內容也是html的格式。
    chartset:文本編碼,中文爲“utf-8”

# 構造TEXT格式的消息
  msg = MIMEText("hello.text","plain","utf-8")
  msg["Subject"] = "xxxxx"
  msg["From"] = "xxxx"
  msg["To"] = "xxxx"

# 發送以上構造的郵件內容要使用as_string將構造的郵件內容轉換爲string形式。
  s.sendmail("xxx","xxx",msg.as_string)

2.MIMEImage,MIMEMultipart語法

msg = MIMEMultipart()

# 實例化一個文本對象 
msg_sub = MIMEText("hello.text","plain","utf-8")

# 將text消息添加到MIMEMultipart中,作爲郵件正文。
msg.attach(msg_sub)

# 圖片作爲附件
import os
img_datas = open(os.getcwd()+ "/reports/xxxx.png","rb").read()
msg_img = MIMEImage(img_data)
msg_img.add_header('Content-Disposition','attachment', filename = "xxxx.png" )
msg_img.add_header('Content-ID','<0>')

# 將圖片添加到MIMEMultiplart中,作爲附件發送。
msg.attach(mag_img)

二、可以發送不同格式的郵件

發送文本郵件

# coding=utf-8
import smtplib
from email.mime.text import MIMEText
# 發送純文本格式的郵件
msg = MIMEText('hello,send by python_test...','plain','utf-8')
sender = '[email protected]'  # 發送郵箱地址
password = 'xxxxxxx'        # 郵箱授權碼,非登陸密碼
mailto_list = ['[email protected]']  # 羣發郵箱地址
smtp_server = 'smtp.163.com'  # smtp服務器
msg['From'] = sender          # 發送郵箱地址
msg['To'] =';'.join(mailto_list)  # 發送多人郵件寫法
msg['Subject'] = 'hello,i just want to test'  # 主題 
server = smtplib.SMTP(smtp_server,25)  # SMTP協議默認端口是25
server.login(sender,password)          # ogin()方法用來登錄SMTP服務器
server.set_debuglevel(1)               # 打印出和SMTP服務器交互的所有信息。
server.sendmail(sender,mailto_list,msg.as_string()) # msg.as_string()把MIMEText對象變成str server.quit()
# 第一個參數爲發送者,第二個參數爲接收者,可以添加多個例如:['[email protected]','[email protected]',]# 第三個參數爲發送的內容
server.quit()

查看和SMTP服務器交互的所有信息:

其中login()用來登陸SMTP服務器,sendmail()用來發送郵件,羣發郵件的話,可以傳入一個收件人郵箱列表,郵箱的正文是str,使用as_string()把MIMEText對象變成str,password指的不是smtp服務器的登陸密碼,是smtp客戶端的授權密碼:

發送帶HTML的郵件:

import smtplib
from email.mime.text import MIMEText
from email.header import Header

sender = '[email protected]' # 發件郵箱
passwd = 'xxxxxxxx'        # 發送人郵箱授權碼
receivers = '[email protected]'   # 收件郵箱
subject = 'python發郵Html郵件測試' # 主題

content = "<html><h1>人生苦短,何必執着</h1></html>"
msg = MIMEText(content,'html','utf-8')
# msg['Subject'] = subject
msg['Subject'] = Header(subject,'utf-8')
# msg['From'] = sender
msg['From'] = Header('hello','utf-8')
# msg['To'] = receivers
msg['To'] = Header('emmmm','utf-8')
try:
    s = smtplib.SMTP_SSL('smtp.163.com',25)
    s.login(sender,passwd)
    s.sendmail(sender,receivers,msg.as_string())
    print('Send Success')
except:
    print('Send Failure')

發送帶圖片附件的郵件:

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

sender = '[email protected]'
passwd = 'xxxxxxxx'
receivers = '[email protected]'
subject = 'python發郵帶img的郵件測試' # 主題

# 創建一個帶附件的實例
msg = MIMEMultipart()
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = receivers

# 創建正文
msg.attach(MIMEText('使用python smtplib模塊和email模塊自動發送郵件測試','plain','utf-8'))

# 創建圖片附件
import os
img_file = open(os.getcwd()+"/a4.jpg",'rb').read()
msg_img = MIMEImage(img_file)
msg_img.add_header('Content-Disposition','attachment', filename = "a4.jpg")
msg_img.add_header('Content-ID', '<0>')
msg.attach(msg_img)

try:
    s = smtplib.SMTP('smtp.163.com',25)
    s.set_debuglevel(1) # 輸出發送郵件詳細過程
    s.login(sender,passwd)
    s.sendmail(sender,receivers,msg.as_string())
    print('Send Succese')

except:
    print('Send Failure')

發送帶附件的郵件:

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

sender = '[email protected]'  # 發件郵箱
passwd = 'xxxxxxxxxx'       # 郵箱授權碼
receivers = '[email protected]'# 收件郵箱

subject = 'python髮帶附件的郵件測試' # 主題
msg = MIMEMultipart()              # 創建一個帶附件的實例 
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = receivers

# 創建正文,將文本文件添加到MIMEMultipart中
msg.attach(MIMEText('使用python smtplib模塊和email模塊自動發送郵件測試','plain','utf-8'))

# 構造附件1,傳送當前目錄下文件
att1 = MIMEText(open('testdata.xlsx','rb').read(),'base64','utf-8') # rb以二進制方式讀取
# att1["Content-Type"] = 'application/octet-stream'
# filename爲附件名稱,可以任意寫,寫什麼名字,郵件中顯示什麼名字
att1["Content-Disposition"] = 'attachment; filename = "testdata.xlsx" '
#將附件添加到MIMEMultipart中
msg.attach(att1)

#構造附件2
att2 = MIMEText(open('db.cfg','rb').read(),'base64','utf-8')
# att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename = "db.cfg" '
#將附件添加到MIMEMultipart中
msg.attach(att2)

try:
    s = smtplib.SMTP('smtp.qq.com',25)
    s.set_debuglevel(1) # 輸出發送郵件詳細過程
    s.login(sender,passwd)
    s.sendmail(sender,receivers,msg.as_string())
    print('Send Succese')

except:
    print('Send Failure')

發送HTML與圖片格式的郵件

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

sender = '[email protected]'      # 這裏就是你的163郵箱
receiver = '[email protected]'     # 發給單人時的郵件接收郵箱
smtpserver = "smtp.163.com" # 郵件服務器,如果是163郵箱那就是這個了,其他的可以自行查找
username = '[email protected]'   # 這裏還是你的郵箱
password = 'xxxxx'          # 上面獲取的SMTP授權碼,相當於是一個密碼驗證
msgRoot = MIMEMultipart('related') # 郵件類型,如果要加圖片等附件,就得是這個
msgRoot['Subject'] = '監控日報'     # 郵件標題,以下設置項都很明瞭
msgRoot['From'] = sender
msgRoot['To'] = receiver # 發給單人

# 以下爲郵件正文內容,含有一個居中的標題和一張圖片
content = MIMEText('<html><head><style>#string{text-align:center;font-size:25px;}</style><div id="string">我是居中顯示的標題<div></head><body><img src="cid:image1" alt="image1"></body></html>','html','utf-8')

# 如果有編碼格式問題導致亂碼,可以進行格式轉換:
# content = content.decode('utf-8').encode('gbk')
msgRoot.attach(content)

# 上面加的圖片src必須是cid:xxx的形式,xxx就是下面添加圖片時設置的圖片id
# 添加圖片附件
fp = open('D:\\Desktop\\201283116221721201.jpg', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()
msgImage.add_header('Content-ID', 'image1') # 這個id用於上面html獲取圖片
msgRoot.attach(msgImage)
'''
# 另外也可以用base64的方法直接加:
import base64
img_file = open('C:\\Users\\cloudoxou\\Desktop\\img.png','rb')
base64_data = base64.b64encode(img_file.read())
html = "<img src="data:image/png;base64,%s" alt="image1">"%(base64_data) # 這裏簡化了html代碼
'''
# 連接郵件服務器,因爲使用SMTP授權碼的方式登錄,必須是994端口
smtp = smtplib.SMTP_SSL(smtpserver,994)
smtp.login(username, password)
smtp.sendmail(sender, receiver, msgRoot.as_string())

msg中輸入的是郵件正文,因此需要根據具體內容格式選擇合適的類型!

關於不同類型文件的對應類型,可參考此鏈接:HTTP Content-type 對照表

 

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