一、smtplib模塊
SMTP 簡單郵件傳輸協議,是專門用於發送電子郵件的協議。
SMTP規定了電子郵件應該如何格式化、加密、在郵件服務器之間傳遞,以及點擊發送後計算機要處理的所有其他細節。
利用Python自帶的smtplib模塊,我們可以實現從第三方SMTP服務器(比如QQ郵箱)登錄併發送電子郵件。
——
1. smtplib使用步驟
代碼演示:
import smtplib
# 第一步:創建SMTP服務器對象
smtpobj = smtplib.SMTP('smtp.qq.com',587)
# 第二步:首先跟服務器打招呼
smtpobj.ehlo()
# 第三步:如果連接的SMTP的587端口,需要進行連接加密步驟(如果是465端口則可以跳過)
smtpobj.starttls()
# 第四步:登錄到SMTP服務器
smtpobj.login('*******@qq.com','aaaabbbbccc')
# 輸入郵箱賬號以及授權碼(這裏並不是輸入郵箱密碼)
# 第五步:發送電子郵件(發件地址,收件地址,內容)
smtpobj.sendmail('*******@qq.com', '########@qq.com',
'Subject: So long. \nDear Alice, so long and thanks for all the fish. Sincerely,Bob') # Subject爲郵件主題,通過換行符(\n)來區分主題和正文
#第六步:從SMTP服務器斷開
smtpobj.quit()
——
2. 兩個重點關注的點
需要重要說明的兩個地方:
【01】如何開啓第三方SMTP服務器並獲得授權碼
以QQ郵箱爲例,登錄自己的QQ郵箱,進入 [設置-賬戶],即可看到關於SMTP服務開啓的選項,點擊開啓,按照提示要求進行,即可打開我們QQ郵箱的SMTP服務並獲得相對應的授權碼。
【02】郵件發送中無法使用中文的問題
如果郵件內容中有中文字符
# 第五步:發送電子郵件(發件地址,收件地址,內容)
smtpobj.sendmail('*******@qq.com', '########@qq.com',
'Subject: 大家好\n你好,你好鴨!') # 無法使用中文字符
會出現以下報錯
本人也查閱了相關資料,發現該錯誤一般是出現在Python2的版本中,Python3默認字符集基本都是"utf-8"。
所以也不清楚爲啥會出現無法使用中文的情況(要是哪些大神知道這是啥原因,懇請指點一二!)
那就意味着我們不能發中文內容的郵件呢麼?
當然不是,在smtplib基礎上結合email,我們就能實現。
二、email模塊
smtplib與email相結合,我們能夠實現更加強大的發送郵件功能,不僅能夠發送純文本,還能夠發送html文本郵件、正文中含有圖片的郵件以及帶有附件的郵件。
那麼我們首先來認識瞭解一下email模塊中我們常用的函數方法。
——
1. 常用函數詳解
from email.header import Header
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
通過使用Header()函數,我們可以定義郵件頭信息,比如From(發件人)、To(收件人)、Subject(郵件主題)。
msg_root['From'] = Header('逆旅鴨<*******@qq.com>','utf-8') # 發件人
msg_root['To'] = Header('李XXX<&&&&&&&&@qq.com>','utf-8') # 收件人
subject = '好久不見,別來無恙'
msg_root['subject'] = Header(subject,'utf-8') # 郵件主題
關於MIMEText、MIMEImage和MIMEMultipart最好放在一起解釋。
- 首先這個三個都是用來構造郵件對象
- MIMEText表示文本對象,包含三個值(正文內容,正文類型,正文內容編碼)。正文類型有"plain"純文本,"html"超文本。
- MIMEImage表示圖片對象,通過使用MIMEImage,我們能夠在正文內容中顯示圖片
- MIMEMultipart,表示整個郵件,可以將多個對象組合在一起。
重點說下MIMEMultipart,它的參數有三個值
- alternative:郵件正文包括純文本和超文本;
- related:郵件正文除了文本,還包括圖片、聲音等內嵌資源;
- mixed:郵件包含文本、圖片、附件等等內容,基本上包括了所有可發送內容。一般情況下我們使用的是它。
——
2. 郵件構造原理
一張圖告訴你email郵件構造原理
- 創建MIMEMultipart(‘mixed’)
- 根據個人需求,分別構造純文本、超文本、正文帶圖片、帶附件的部分
- 再將以上部分通過attach()方法添加到MIMEMultipart對象中
簡單列下每個內容構造的代碼
【01】構造純文本
text_info = 'Hello world!'
text_sub = MIMEText(text_info, 'plain', 'utf-8')
msg_root.attach(text_sub) # 將純文本對象添加到MIMEMultipart對象
【02】構造超文本
html_info = """
<p>CSDN首頁</p>
<p><a href="https://www.csdn.net/">歡迎進入CSDN</a></p>
"""
html_sub = MIMEText(html_info, 'html', 'utf-8')
msg_root.attach(html_sub) # 將超文本對象添加到MIMEMultipart對象
【03】構造正文顯示圖片
# 要在正文顯示圖片,需要先構造超文本
html_info = """
<p>圖片演示:</p>
<p><img src="cid:image1"></p>
"""
html_sub = MIMEText(html_info, 'html', 'utf-8')
msg_root.attach(html_sub) # 將超文本對象添加到MIMEMultipart對象
image_file = open(pic_address, 'rb').read()
image = MIMEImage(image_file)
image.add_header('Content-ID', '<image1>') # 將圖片命名
msg_root.attach(image) # 將圖片對象添加到MIMEMultipart對象
【04】構造附件
enc_file = open(enc_address,'rb').read()
enc = MIMEText(enc_file, 'base64', 'utf-8') # 注意這裏要加入參數'base64'
enc['Content-Type'] = 'application/octet-stream'
enc.add_header('Content-Disposition', 'attachment', filename=enc_name) # 給附件命名
msg_root.attach(enc) # 將附件對象添加到MIMEMultipart對象
以上就是關於email模塊的介紹,基本上能夠滿足於我們日常的發送電子郵件需求了。
在下一部分我會整合smtplib與email的使用,通過使用構造函數的方式,讓整個代碼更加清晰易懂且方便。
三、smtp+email輕鬆發送郵件
代碼演示如下:
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
# 【01】構建郵件頭部信息
def basic_info(from1, to1, subject1):
msg_root['From'] = Header(from1,'utf-8') # 發件人
msg_root['To'] = Header(to1,'utf-8') # 收件人
subject = subject1
msg_root['subject'] = Header(subject,'utf-8') # 郵件主題
# 【02】構造文本內容
def text(text1):
text_info = text1
text_sub = MIMEText(text_info, 'plain', 'utf-8')
msg_root.attach(text_sub)
# 【03】構造超文本
def html(hype_text):
html_info = hype_text
html_sub = MIMEText(html_info, 'html', 'utf-8')
msg_root.attach(html_sub)
# 【04】構造正文顯示圖片
def image(pic_address):
image_file = open(pic_address, 'rb').read()
image = MIMEImage(image_file)
image.add_header('Content-ID', '<image1>')
msg_root.attach(image)
#【05】構造附件
def enclosure(enc_address, enc_name):
enc_file = open(enc_address,'rb').read()
enc = MIMEText(enc_file, 'base64', 'utf-8')
enc['Content-Type'] = 'application/octet-stream'
enc.add_header('Content-Disposition', 'attachment', filename=enc_name)
msg_root.attach(enc)
# 【06】程序主體
try:
mail_host = 'smtp.qq.com' # QQ郵箱SMTP服務器地址
mail_user = '*********@qq.com' # 郵箱賬號
mail_pass = 'aaaabbbbbbcccccc' # 郵箱授權碼
sender = '[email protected]' # 發件人郵箱地址
receivers = ['%%%%%%%%%@qq.com'] # 收件人郵箱地址
smtpobj = smtplib.SMTP() # 創建SMTP對象
smtpobj.connect(mail_host, 587) # 連接郵箱SMTP服務器
smtpobj.login(mail_user, mail_pass) # 登錄SMTP服務器
msg_root = MIMEMultipart('mixed')
basic_info('逆旅鴨','李XX','郵件發送測試') # 寫入郵件頭部信息
text('這是 Python 郵件發送測試....') # 在正文內容寫入純文本
# 如果要在正文顯示圖片,需要在html中寫入
html_text = """
<p>CSDN首頁</p>
<p><a href="https://www.csdn.net/">歡迎進入CSDN</a></p>
<p>圖片演示:</p>
<p><img src="cid:image1"></p>
"""
html(html_text) # 在正文內容寫入超文本
image('開啓QQ郵箱的SMTP服務.png') # 在正文內容顯示圖片
enclosure('test.txt', '紀念品.txt') # 添加附件並命名“紀念品.txt”
smtpobj.sendmail(sender,receivers,msg_root.as_string()) # 發送電子郵件
print('郵件發送成功')
smtpobj.quit() # 斷開SMTP服務器
except smtplib.SMTPException:
print('Error: 無法發送郵件')
最後運行程序,就會在郵箱中接受到這樣一封郵件
四、覆盤總結
- 以QQ郵箱爲例,我們如果要利用python發送電子郵件,需要打開QQ郵箱的SMTP服務,並獲得授權碼
- 關於smtplib與email模塊的結合使用:利用smptlib實現連接、登錄以及最終的郵件發送功能,利用email來構造整個郵件體
- 熟練掌握email模塊中最常用的4個功能:Header()、MIMEText()、MIMEImage()、MIMEMultipart()