使用 smtplib 傳送郵件

TNT_God發表於2020-03-13

前幾天看到了很多關於smtplib的教程,幾乎所有教程例子的程式碼都挺複雜的(感覺對smtplib新手不是很友好)。所以,我想教大家如何最簡單地實現傳送郵件。

smtplib介紹

SMTP(Simple Mail Transfer Protocol)即簡單郵件傳輸協議,它是一組用於由源地址到目的地址傳送郵件的規則,由它來控制信件的中轉方式。python的smtplib提供了一種很方便的途徑傳送電子郵件。它對smtp協議進行了簡單的封裝。

程式碼結構

廢話不多說,首先把程式碼的結構獻上

import smtplib
obj = smtplib.SMTP(你郵箱的協議,你郵箱支援的埠)
obj.ehlo()
obj.starttls()
obj.login(你的郵箱名,密碼)
obj.sendmail(你的郵箱名,收件郵箱,'Subject:標題\n\n內容')
obj.quit()

程式碼解析

import smtplib

匯入smtplib,這個相信大家都知道。

obj = smtplib.SMTP(郵箱協議,你的郵箱支援的埠)

使用smtplib.SMTP來建立一個你郵箱的物件。這個“郵箱協議”就是你的郵箱的smtp協議,然後還要加上“你的郵箱支援的埠”,有些郵箱支援456埠,有些支援587埠,我會把每個不同的電子郵箱所支援的smtp協議和支援的埠放到最後,方便大家去查訊。
郵箱協議:傳入字串
你的郵箱支援的埠:傳輸數字即可

注意!有時候執行這段程式碼的時候,會出現“由於連線方在一段時間後沒有正確答覆或連線的主機沒有反應,連線嘗試失敗。”的錯誤,這種情況重新執行程式碼就行了。還有,如果你是qq郵箱或網易郵箱,就需要開啟smtp協議。不知道的朋友可以百度一下。

obj.ehlo()

ehlo()這一步可以加上也可以不加。這個函式用來判斷目前是否有異常,無異常就會返回一個包含250的值的括號。

注意!如果你是指令碼式執行的,就不會返回結果,只有互動式執行才回返回結果這種情況,你只需要print(obj.ehlo()),這樣無論是互動式還是指令碼式都會返回結果了!

obj.starttls()

starttls()這個函式用於進行tls加密,如果你在smtplib.SMTP函式那步的第二個引數,也就是你的郵箱支援的埠是465,那麼,這一步就可以跳過了。因為465埠已經進行了ssl加密了。如果加密成功的話,就會返回一個帶220值的括號。
和ehlo()函式一樣,需要print(obj.starttls())

obj.login(你的郵箱名,密碼)

login中文就是登入的意思,也就是說開始登陸,需要傳入的引數是你的郵箱名和郵箱密碼。
你的郵箱名:字串
密碼:字串

注意:如果你是qq郵箱或網易郵箱,傳入的不能是密碼!需要傳入smtp協議的授權碼。和密碼一樣,授權碼傳入字串,而且傳入授權碼的時候,要把所有字母改為小寫,授權碼之間不能有空格!否則login()函式不知道你已經傳入了授權碼!

obj.sendmail(你的郵箱名,收件郵箱,'Subject:標題\n\n內容')

“你的郵箱名”就是要傳入你的完整郵箱名字,收件郵箱就是傳送郵件的目標的完整郵箱名。接著,有人就會開始覺得奇怪了。為什麼我要加上一個Subject:標題\n\n內容。我並不是用來標記,而是在傳送郵件的時候必須要這樣寫。“Subject:”冒號後面用來輸標題名,然後需要兩個\n來進行換行從標題輸入框跳到內容輸入框。

你的郵箱名:字串
收件郵箱:字串
標題和內容:字串

obj.quit()

接著,還需要退出伺服器才能正確傳送。
這就是一個程式碼例項:

import smtplib
obj = smtplib.SMTP('smtp.qq.com',587)
obj.starttls()
obj.login('example@qq.com',授權碼)#我使用的是qq郵箱,所以不能輸入密碼
obj.sendmail('example@qq.com','go@hotmail.com','Subject:Hi\n\nTNT!')
obj.quit()

結果:

太棒了!再來一次!
我們不是中國人嗎?試一次中文!!!
這次的程式碼:

import smtplib
obj = smtplib.SMTP('smtp.qq.com',587)
obj.starttls()
obj.login('example@qq.com',授權碼)#我使用的是qq郵箱,所以不能輸入密碼
obj.sendmail('example@qq.com','go@hotmail.com','Subject:中文測試\n\n我失敗了')
obj.quit()

完了,報錯了!
File “C:\Users\Administrator\AppData\Local\Programs\Python\Python37-32\lib!smtplib.py”, line 855, in sendmail
msg = _fix_eols(msg).encode(‘ascii’)
UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 8-13: ordinal not in range(128)

錯誤解析

在傳送郵件的時候,smtplib需要把內容進行編碼。報錯的內容就說是在編碼內容成ascii的時候出現了錯誤。當我們檢視一下ascii編碼列表的時候,發現沒有中文字元的編碼結果!怎麼辦呢?在傳送內容的時候,其實不僅可以編碼成為ascii還能編碼成utf-8!所以呢,我們要改一下主程式程式碼。請大家按照自己的錯誤資訊所指的報錯檔案,一般都是C:/program files/python(我這裡因為一些需求,安裝到了不同的目錄,請大家不要複製我的目錄)。
然後,在主程式的第855行,把msg = _fix_eols(msg).encode(‘ascii’)改成msg = _fix_eols(msg).encode(‘utf-8)就行了,接著,回到我們的程式,再來跑一次程式碼!
結果:
使用smtplib傳送郵件

我 們 完 成 了!

不同的郵箱協議和支援的埠

注意:這裡只顯示一部分著名的郵箱

  • 網易郵箱 協議:smtp.163.com 埠:465
  • Hotmail/outlook 協議:smtp-mail.outlook.com 埠:587
  • Gmail 協議:smtp.gmail.com 埠:587
  • qq郵箱 協議:smtp.qq.com 埠:465/587
  • Yahoo 協議:smtp.mail.yahoo.com 埠:587

需要什麼幫助的話請加群號:773940913,或在評論區提問。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

The best and the worst

相關文章