Python 第三方模塊之 smtplib

1 python對SMTP的支持

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

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

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

1.1 smtp 模塊

1、創建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 即可。?#################### 示例一
smtp = smtplib.SMTP()
smtp.connect([host[,port]])  # 連接遠程smtp主機方法,host為遠程主機地址,port為遠程主機smtp端口,默認為25,也可以直接使用host:port形式來表示,例如:SMTP.connect("smtp.163.com","25")
smtp.starttls()                       # 開啟安全傳輸模式
smtp.login("test@arcvideo.com","pwd") # 郵箱賬號登錄校驗
smtp.sendmail(FROM, [TO], BODY)       # 郵件發送
smtp.quit()                           # 斷開smtp連接#################### 示例二
smtp = smtplib.SMTP([host[,port]])
smtp.login("test@arcvideo.com","pwd") # 郵箱賬號登錄校驗
smtp.set_debuglevel(1)                # 打印出和SMTP服務器交互的所有信息。
smtp.sendmail(FROM, [TO], BODY)       # 郵件發送
smtp.quit()                           # 斷開smtp連接

2、SMTP對象使用sendmail方法發送郵件:

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

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

SMTP類有幾個常用的方法:

方法

描述

SMTP.set_debuglevel(level)設置輸出debug調試信息,默認不輸出
SMTP.docmd(cmd[, argstring])發送一個命令到SMTP服務器
SMTP.connect([host[, port]])連接到指定的SMTP服務器
SMTP.helo([hostname])使用helo指令向SMTP服務器確認你的身份
SMTP.ehlo(hostname)使用ehlo指令像ESMTP(SMTP擴展)確認你的身份
SMTP.ehlo_or_helo_if_needed()如果在以前的會話連接中沒有提供ehlo或者helo指令,這個方法會調用ehlo()或helo()
SMTP.has_extn(name)判斷指定名稱是否在SMTP服務器上
SMTP.verify(address)判斷郵件地址是否在SMTP服務器上
SMTP.starttls([keyfile[, certfile]])使SMTP連接運行在TLS模式,所有的SMTP指令都會被加密
SMTP.login(user, password)登錄SMTP服務器
SMTP.sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[])

發送郵件

from_addr:郵件發件人

to_addrs:郵件收件人

msg:發送消息

SMTP.quit()關閉SMTP會話
SMTP.close()關閉SMTP服務器連接

1.2 MIME

通過郵件傳輸簡單的文本已經無法滿足我們的需求,比如我們時常會定制業務質量報表,在郵件主體中會包含 HTML、圖像、聲音以及附件格式等,MIME(Multipurpose Internet Mail?Extensions,多用途互聯網郵件擴展)作為一種新的擴展郵件格式很好地補充了這一點,更多MIME 知識見?email — An email and MIME handling package — Python 3.10.2 documentation。下面介紹幾個 Python 中常用的 MIME 實現類:

MIMEBase

email.mime.base.MIMEBase(_maintype,_subtype,*,policy = compat32,** _ params?):

這是所有MIME特定類的基類

  • _maintpe是Content-Type主要類型(text or image)
  • _subtype是Content-Type次要類型(plain or gif)
  • _params是一個鍵值字典參數直接傳遞給Message.add_header
filename1 = '圖片.pdf'
attachfile_base = MIMEBase('application', 'octet-stream')  # 創建基礎對象指定類型
attachfile_base.set_payload(open(filename,'rb').read())    # 設置我有效負載# 設置文件名可用中文
attachfile_base.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', filename1))
attachfile_base.add_header('Content-Disposition', 'attachment', filename=filename1 .encode('UTF-8'))encoders.encode_base64(attachfile_base)
msg.attach(attachfile_base)

MIMEMultipart

email.mime.multipart.MIMEMultipart(_subtype='mixed',boundary= None,_subparts = None,*,policy = compat32,** _ params ):

作用是生成包含多個部分的郵件體的 MIME 對象

  • _subtype 指定要添加到"Content-type:multipart/subtype" 報頭的可選的三種子類型,分別為 mixed、related、alternative,默認值為 mixed。定義 mixed實現構建一個帶附件的郵件體;定義related 實現構建內嵌資源的郵件體;定義alternative 則實現構建純文本與超文本共存的郵件體;
  • _subparts是有效負載的一系類初始部分,可以使用attach()方法將子部件附加到消息中。
from email.mime.multipart import MIMEMultipartmsg1 = MIMEMultipart('mixed')  # 創建帶附件的實例
msg2 = MIMEMultipart('related')  # 創建內嵌資源的實例
msg3 = MIMEMultipart('alternative') # 創建純文本與超文本實例

MIMEApplication

email.mime.application.MIMEApplication(_data,?_subtype='octet-stream',?_encoder=email.encoders.encode_base64,?*,?policy=compat32,?**_params):

被用來表示主要類型的MIME消息對象應用

  • _data是一個包含原始字節數據的字符串
  • _subtype指定MIME子類型默認為八位字節流
  • _encoder是一個可調用函數,它執行傳輸數據的實際編碼,使用set_payload()將有效載荷改為編碼形式,默認編碼位base64,可使用email.encoders模塊查看內置編碼表。
filename = 'abc.pdf'
with open(filename,'rb') as f:attachfile = MIMEApplication(f.read())
attachfile.add_header('Content-Disposition', 'attachment', filename=filename)
msg.attach(attachfile)

MIMEAudio

email.mime.audio.MIMEAudio (_audiodata[, _subtype[, _encoder]]):

創建包含音頻數據的郵件體

  • _audiodata 包含原始二進制音頻數據的字節字符串;
  • _subtype音頻類型,
  • _encoder編碼。
from email.mime.audio import MIMEAudiomsgaudio = MIMEAudio(open('yishengsuoai.mp3','rb').read(),'plain')  # 文本音頻對象msgaudio.add_header('Content-Disposition','attachment',filename='text.mp3')  # 擴展標題類型,文件名
msg.attach(msgaudio)  # 附加對象加入到msg

MIMEImage

email.mime.image.MIMEImage(_imagedata[, _subtype[, _encoder[, **_params]]]):

MIMENonMultipart中的一個子類,創建包含圖片數據的郵件體,

  • _imagedata 是包含原始圖片數據的字節字符串;
  • _sutype指定圖像子類型;
  • _encoder指定一個函數內部編碼默認為:email.encoders.encode_base64默認為base64編碼
from email.mime.image import MIMEImage with open('test.png','rb') as fp:msgImage = MIMEImage(fp.read()) msgImage.add_header('Content-ID','imgid')  # 為圖片對象拓展標題字段和值
msg.attach(msgImage)  # 將圖像負載添加到msg負載

MIMEText

email.mime.text.MIMEText (_text[, _subtype[, _charset]]):

MIMENonMultipart中的一個子類,創建包含文本數據的郵件體

  • _text 是包含消息負載的字符串,
  • _subtype 指定文本類型,支持 plain(默認值)或 html類型的字符串。發送HTML格式的時候,修改為html,但同時要求msg的內容也是html的格式。
  • _charset設置字符集,參數接受一個charset實例。
from email.mime.text import MIMEText# 創建文本內容的郵件體
msg = MIMEText("python test email",'plain','utf-8')# 創建HTML格式的郵件體
msg = MIMEText("<p>python test email</p><p><a href="http://www.demo.com">鏈接</a></p>",'html','utf-8')# 構造TEXT格式的消息
msg = MIMEText("hello.text","plain","utf-8")
msg["Subject"] = "xxxxx"  # 主題
msg["From"] = "xxxx"      # 發送者
msg["To"] = "xxxx"        # 接收者
msg["Cc"] = "xxxx"        # 抄送# 發送以上構造的郵件內容要使用as_string將構造的郵件內容轉換為string形式。
msg.sendmail("xxx","xxx",msg.as_string)

MIME實例對象的方法:

  • as_string() :返回字符串信息,相當于__str__(),str(msg)
  • as_bytes() :返回字節信息,相當于__bytes__(),bytes(msg)
  • is_multipart() :判斷是否為有效載荷的列表message對象,是返回True,否則返回False
  • set_unixfrom(unixfrom) :將消息的信封頭設置為unixfrom為字符串
  • get_unixfrom() :返回消息的信封頭。默認為None
  • attach(payload) :將給定的有效負載添加到當前有效負載
  • get_payload(i=None, decode=False) :返回當前的有效載荷,這將是一個列表 Message
  • set_payload(payload, charset=None) :將整個消息對象的有效載荷設置為有效載荷
  • set_charset(charset) ;將有效負載的字符集設置為charset
  • get_charset() :返回Charset與消息有效負載相關的實例
  • __len__() :返回標題的總數,包括重復項
  • __contains__(name) :如果消息對象具有名為name的字段,則返回true
  • __getitem__(name) :返回指定標題字段的值
  • __setitem__(name, val) :將字段添加到帶有字段名稱和值val的消息中
  • __delitem__(name) :從消息的標題中刪除所有出現的具有名稱name的字段
  • keys() :返回所有消息標題字段名稱的列表
  • values() :返回所有消息字段值的列表
  • items() :返回包含所有消息的字段標題和值
  • add_header(_name, _value, **_params) :擴展標題設置,_name為要添加的標題字段,_value為標題的值。
msg.add_header('Content-ID','imgid')   #設置圖片ID
msg.add_header('Content-Disposition','attachment',filename='test.xlsx') #為附件添加一個標題
msg.add_header('Content-Disposition','attachment',filename=('utf-8','','中文標題')) #添加非ASCII字符時需指定編碼
  • replace_header(_name,_value) :替換標題

更多內容請閱讀官方文檔

email.header.Header(s=None,charset=None):創建一個可以包含不同字符集中的字符串,并符合MIME的標頭。

可選參數:s是初始標題值默認為None,可以使用append()方法追加到標題,charset指定字符集

from email.header import Headermsg['From'] = Header("測試郵件來自",'utf-8')

附加工具:email.utils

  • email.utils.localtime(dt=None):返回當前時間,dt參數為datetime實例
  • email.utils.formataddr(pair,charset='utf-8'):pair是一個元祖或列表返回分割的標題和地址如郵箱收件人昵稱和郵箱賬號
from email.utils import formataddrmsg['From'] = formataddr(['Meslef','92066@163.com'])
msg['To'] = formataddr(['Anybody','92066@163.com'])

2 可以發送不同格式的郵件

2.1 發送文本郵件

# coding=utf-8
import smtplib
from email.mime.text import MIMETextsender = 'bmjoker@163.com'  # 發送郵箱地址
password = 'xxxxxxx'        # 郵箱授權碼,非登陸密碼
mailto_list = ['19xxxxxxx9@qq.com']  # 群發郵箱地址
smtp_server = 'smtp.163.com'  # smtp服務器# 發送純文本格式的郵件
msg = MIMEText('hello,send by python_test...','plain','utf-8')
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)          # login()方法用來登錄SMTP服務器
server.set_debuglevel(1)               # 打印出和SMTP服務器交互的所有信息。
server.sendmail(sender,mailto_list,msg.as_string()) # msg.as_string()把MIMEText對象變成str server.quit()
# 第一個參數為發送者,第二個參數為接收者,可以添加多個例如:['hello@163.com','xxx@qq.com',]# 第三個參數為發送的內容
server.quit()

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

?

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

?

2.2 發送帶HTML的郵件:

import smtplib
from email.mime.text import MIMEText
from email.header import Headersender = 'bmjoker@163.com'        # 發件郵箱
passwd = 'xxxxxxxx'               # 發送人郵箱授權碼
receivers = '19xxxxxxx9@qq.com'   # 收件郵箱
subject = 'python發郵Html郵件測試' # 主題content = "<html><h1>人生苦短,何必執著</h1></html>"
msg = MIMEText(content,'html','utf-8')
msg['Subject'] = Header(subject,'utf-8')  # msg['Subject'] = subject
msg['From'] = Header('hello','utf-8')     # msg['From'] = sender
msg['To'] = Header('emmmm','utf-8')       # msg['To'] = receiverstry: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')

2.3 發送帶圖片附件的郵件:

import smtplib
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipartsender = 'bmjoker@163.com'
passwd = 'xxxxxxxx'
receivers = '19xxxxxx9@qq.com'
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')

調整圖片大小?

<!--有效-->
<img src="cid:ALogo"  width="500" height="200"><!--無效-->
<img src="cid:ALogo" style="width: 500px;height: 200px"><!--無效-->
<img src="cid:ALogo" width="500px" height="200px">

2.4 發送帶附件的郵件:

# 首先是xlsx類型的附件
xlsxpart = MIMEApplication(open('test.xlsx', 'rb').read())
xlsxpart.add_header('Content-Disposition', 'attachment', filename='test.xlsx')
msg.attach(xlsxpart)# jpg類型的附件
jpgpart = MIMEApplication(open('beauty.jpg', 'rb').read())
jpgpart.add_header('Content-Disposition', 'attachment', filename='beauty.jpg')
msg.attach(jpgpart)# mp3類型的附件
mp3part = MIMEApplication(open('kenny.mp3', 'rb').read())
mp3part.add_header('Content-Disposition', 'attachment', filename='benny.mp3')
msg.attach(mp3part)##################### 以下待驗證
# 讀取xls文件作為附件,open()要帶參數'rb',使文件變成二進制格式,從而使'base64'編碼產生作用,否則附件打開亂碼
# att = MIMEText(open('C:\\ceshi.xls', 'rb').read(), 'base64', 'GB2312')
# att['Content-Type'] = 'application/vnd.ms-excel'
# att['Content-Disposition'] = 'attachment; filename ="1.xls"'# 讀取xlsx文件作為附件,open()要帶參數'rb',使文件變成二進制格式,從而使'base64'編碼產生作用,否則附件打開亂碼
att = MIMEText(open(u'C:\\ceshi.xlsx', 'rb').read(), 'base64', 'utf-8')
att['Content-Type'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
#下面的filename 等號(=)后面好像不能有空格
attname ='attachment; filename ="123.xlsx"'
att['Content-Disposition'] = attnamemsgroot.attach(att)

#encoding=utf8
import smtplib
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
# 第三方 SMTP 服務
mail_host = "*******"  # 設置服務器
mail_user = "*******"  # 用戶名
mail_pass = "********"  # 口令sender = '*****'
receivers = ['*****']  # 接收郵件,可設置為你的QQ郵箱或者其他郵箱
content = MIMEText('test')
message = MIMEMultipart()
message.attach(content)
message['From'] = Header("Easy", 'utf-8')
message['To'] = Header("測試", 'utf-8')
subject = 'Python SMTP 郵件測試'
message['Subject'] = Header(subject, 'utf-8')
xlsx = MIMEApplication(open('test.xlsx', 'rb').read())
xlsx["Content-Type"] = 'application/octet-stream'
xlsx.add_header('Content-Disposition', 'attachment', filename='test.xlsx')
message.attach(xlsx)
try:smtpObj = smtplib.SMTP()smtpObj.connect(mail_host, 25)  # 25 為 SMTP 端口號smtpObj.login(mail_user, mail_pass)smtpObj.sendmail(sender, receivers, message.as_string())print("郵件發送成功")
except  Exception as e:print(e)

2.5 發送HTML中帶圖片的郵件

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImagesender = 'xxx@163.com'      # 這里就是你的163郵箱
receiver = 'xxx@qq.com'     # 發給單人時的郵件接收郵箱
smtpserver = "smtp.163.com" # 郵件服務器,如果是163郵箱那就是這個了,其他的可以自行查找
username = 'xxxx@163.com'   # 這里還是你的郵箱
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\\aaa.jpg', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()
msgImage.add_header('Content-ID', 'image')  # 這個id用于上面html獲取圖片
msgRoot.attach(msgImage)
# 再加一個
fp1 = open('D:\\Desktop\\bbb.jpg', 'rb')
msgImage1 = MIMEImage(fp1.read())
fp1.close()
msgImage1.add_header('Content-ID', 'image1') # 這個id用于上面html獲取圖片
msgRoot.attach(msgImage1)'''
# 另外也可以用base64的方法直接加,但是這種方式outlook不支持
import base64
img_file = open('C:\\Users\\cloudoxou\\Desktop\\img.png','rb')
base64_data = base64.b64encode(img_file.read())
html = "<img src="https://img-blog.csdnimg.cn/2022010708251630187.png" 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 對照表。

2.6 匯總

import smtplib
from email.utils import make_msgid,formatdate
from email.mime.text import MIMEText            # html格式和文本格式郵件
from email.mime.multipart import MIMEMultipart  # 帶多個部分的郵件
from email.mime.image import MIMEImage          # 帶圖片格式郵件
from email.mime.audio import MIMEAudio          # 音頻文件對象
from email.utils import formataddr              # 分隔標題與地址
from email.header import Header                 # 設置標題字符集
from email import encoders                      # 編碼器
from email.mime.application import MIMEApplication  # 主要類型的MIME消息對象應用
from email.mime.base import MIMEBaseusername = 'service@gemail.com' # 發件人地址,通過控制臺創建的發件人地址
password = '*****'              # 發件人密碼,通過控制臺創建的發件人密碼
replyto = 'aa@qq.com'           # 自定義的回復地址
rcptto = ['***', '***']         # 收件人地址或是地址列表,支持多個收件人,最多30個# 構建信件標頭結構
msg = MIMEMultipart('alternative')  # 創建一個多部分的郵件對象
msg['Subject'] = Header('自定義信件主題', 'utf-8')
msg['From'] = formataddr([Header('自定義發信昵稱','utf-8'),username])
msg['To'] = formataddr([Header('自定義收信昵稱','utf-8'),rcptto])
msg['Reply-to'] = replyto
msg['Message-id'] = make_msgid() #Message-ID標頭
msg['Date'] = formatdate()  #日期#構建文本郵件內容
msg_text = MIMEText('自定義TEXT純文本部分','plain','utf-8')
msg.attach(msg_text)
#讀取文件創建郵件內容
with open('textfile','rb') as fp:   #讀取文件內容msg_text=MIMEText(fp.read(),'plain','utf-8')#構建HTML格式的郵件內容
msg_html = MIMEText("<h1>HTML格式郵件</h1>","html","utf-8")
msg.attach(msg_html)#構建HTML格式郵件帶圖片內容
html1 = "<div><img src='cid:imgid'></div>"
msg_html_img = MIMEText(html1,'html','utf-8')
msg.attach(msg_html_img)
with open("imgfile","rb") as f:msg_img = MIMEImage(f.read())
msg_img.add_header('Content-ID','imgid') #擴展圖片標題
msg.attach(msg_img)#帶附件的郵件MIMEApplication
filename = '簡歷.pdf'
with open(filename,'rb') as f:attachfile = MIMEApplication(f.read())
attachfile.add_header('Content-Disposition', 'attachment', filename=filename)
msg.attach(attachfile)#帶多個附件的郵件MIMEApplication
filenames = ['簡歷.pdf','副本.pdf']
for tmp in filename:with open(tmp,'rb') as f:attachfiles = MIMEApplication(f.read())attachfiles.add_header('Content-Disposition', 'attachment', filename=tmp)msg.attach(attachfiles)#帶附件的郵件MIMEBase
filename1 = '圖片.pdf'
attachfile_base = MIMEBase('application', 'octet-stream')  #創建基礎對象指定類型
attachfile_base.set_payload(open(filename,'rb').read())  #設置我有效負載
attachfile_base.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', filename1) )
encoders.encode_base64(attachfile_base)
msg.attach(attachfile_base)#創建音頻文件
AUDIO_HTML = '''<p>this's audio file</p><audio controls><source src="cid:audioid" type="audio/mpeg"></audio>
'''
msg_test1 = MIMEText(AUDIO_HTML,'html','utf-8')
msg_audio = MIMEAudio(open('iphone.mp3','rb').read(),'plain')
msg_audio.add_header('Content-ID','audioid')
msg.attach(msg_test1)
msg.attach(msg_audio)
#收到郵件不能播放,有待解決!# 發送郵件
try:client = smtplib.SMTP()#需要使用SSL,可以這樣創建client#client = smtplib.SMTP_SSL()client.connect('smtp.163.com', 25)#開啟DEBUG模式client.set_debuglevel(1)client.login(username, password)client.sendmail(username, rcptto, msg.as_string())client.quit()print('email send success!')
except smtplib.SMTPConnectError as e:print('郵件發送失敗,連接失敗:', e.smtp_code, e.smtp_error)
except smtplib.SMTPAuthenticationError as e:print('郵件發送失敗,認證錯誤:', e.smtp_code, e.smtp_error)
except smtplib.SMTPSenderRefused as e:print('郵件發送失敗,發件人被拒絕:', e.smtp_code, e.smtp_error)
except smtplib.SMTPRecipientsRefused as e:print('郵件發送失敗,收件人被拒絕:', e.smtp_code, e.smtp_error)
except smtplib.SMTPDataError as e:print('郵件發送失敗,數據接收拒絕:', e.smtp_code, e.smtp_error)
except smtplib.SMTPException as e:print('郵件發送失敗, ', e.message)
except Exception as e:print('郵件發送異常, ', str(e))

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/454040.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/454040.shtml
英文地址,請注明出處:http://en.pswp.cn/news/454040.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Node.js 使用jQuery取得Nodejs http服務端返回的JSON對象示例

server.js代碼&#xff1a; // 內置http模塊&#xff0c;提供了http服務器和客戶端功能&#xff08;path模塊也是內置模塊&#xff0c;而mime是附加模塊&#xff09; var httprequire("http");// 創建服務器,創建HTTP服務器要調用http.createServer()函數&#xff0c…

linux下gdb單步調試

用 GDB調試程序 GDB 概述 ———— GDB 是 GNU開源組織發布的一個強大的 UNIX下的程序調試工具。或許&#xff0c;各位比較喜歡那種圖形界面方式的&#xff0c;像 VC、 BCB等 IDE的調試&#xff0c;但如果你是在 UNIX平臺下做軟件&#xff0c;你會發現 GDB這個調試工具有比 V…

svg 動畫_根據AI導出的SVG path制作SVG線條動畫

點擊右上方紅色按鈕關注“web秀”&#xff0c;讓你真正秀起來前言首先祝大家2019新年快樂&#xff0c;萬事大吉&#xff0c;豬事順利&#xff0c;闔家歡樂。前面文章SVG 線條動畫基礎入門知識學習到了基礎知識&#xff0c;現在來給大家講講如何制作SVG 制作復雜圖形線條動畫。假…

MySQL提示Truncated incorrect DOUBLE value解決方法

“Truncated incorrect DOUBLE value”的解決方法主要是這兩種&#xff1a; 1、修改了多個列的值而各列之間用逗號連接而不要用and 錯誤寫法示例&#xff1a;update tablename set col1value1 and col2value2 where col3value3&#xff1b;正確寫法示例&#xff1a;update ta…

一個完美的導航樹

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns"http://www.w3.org/1999/xhtml" ><head><title>無標題頁</title><…

自定義python框架_Python web 框架Sanic 學習: 自定義 Exception

Sanic 是一個和類Flask 的基于Python3.5的web框架&#xff0c;它使用了 Python3 異步特性&#xff0c;有遠超 flask 的性能。編寫 RESTful API 的時候&#xff0c;我們會定義特定的異常錯誤類型&#xff0c;比如我定義的錯誤返回值格式為&#xff1a;{"error_code": …

文字水印

using System.Threading.Tasks;using System.IO;using System.Drawing; public static int Shuy(string Sname,string fname) { try { Image image Image.FromFile(fname); Graphics gra Graphics.FromImage(image); String text Sname; Font font new Font("宋體&quo…

讀書筆記2013第3本:《無價》

《無價》這本書是過年前買的&#xff0c;網絡書店上寫著“老羅推薦”&#xff0c;想著好像是在老羅哪一年的演講里聽過這本書&#xff0c;在豆瓣上評分7.9。讀書是為了產生行動&#xff0c;讀書時要提的4個問題&#xff0c;1&#xff09;這本書主要在談些什么&#xff1f;2&…

Linux下的程序調試——GDB

無論是多么優秀的程序員&#xff0c;都難以保證自己在編寫代碼時不會出現任何錯誤&#xff0c;因此調試是軟件開發過程中的一個必不可少的 組成部分。當程序完成編譯之后&#xff0c;它很可能無法正常運行&#xff0c;或者會徹底崩潰&#xff0c;或者不能實現預期的功能。此時如…

圓錐曲線萬能弦長公式_2020高考數學50條秒殺型公式與方法

考試馬上就要到了&#xff0c;學姐整理了高考數學50條秒殺型公式和方法&#xff0c;希望能幫助考生們更好地攻克數學難關&#xff01;高考數學秒殺公式與方法一1&#xff0c;適用條件&#xff1a;[直線過焦點]&#xff0c;必有ecosA(x-1)/(x1)&#xff0c;其中A為直線與焦點所在…

Python 內置模塊之 logging

日志的級別和適用情況 級別適用情況DEBUG詳細信息&#xff0c;通常只在診斷問題時對其感興趣INFO確認工作正常WARNING表示發生了意料之外的事或者在不遠的將來會有問題&#xff08;比如磁盤空間低&#xff09;。軟件依然正常工作ERROR由于一個更加嚴重的問題&#xff0c;軟件不…

Memory barrier

待續 Memory barrier,是一種屏障和一類指令&#xff0c;在執行這個屏障指令前后&#xff0c;CPU或者編譯器在內存操作上強制一個約束序列。CPU使用性能優化器可以導致執行代碼的無序。在單一線程執行中&#xff0c;重排序內存操作通常不會被注意。但是在并行編程或者設備驅動中…

數據結構與算法 Python語言描述 筆記

數據結構 線性表包括順序表和鏈表&#xff0c;python的list是順序表&#xff0c;鏈表一般在動態語言中不會使用。不過鏈表還是會出現在各種算法題中。 鏈表 link list 單鏈表 逆轉鏈表&#xff1a; leetcode 206雙鏈表循環單鏈表字符串 string 有一個重要的點就是字符串的匹配問…

Flask 跨域問題

一、什么是跨域 跨域是指&#xff1a;瀏覽器A從服務器B獲取的靜態資源&#xff0c;包括Html、Css、Js&#xff0c;然后在Js中通過Ajax訪問C服務器的靜態資源或請求。即&#xff1a;瀏覽器A從B服務器拿的資源&#xff0c;資源中想訪問服務器C的資源。 同源策略是指&#xff1a;…

Hibernate 中配置屬性詳解(hibernate.properties)

轉自&#xff1a;https://blog.csdn.net/shudaqi2010/article/details/70324843 Hibernate能在各種不同環境下工作而設計的, 因此存在著大量的配置參數。多數配置參數都 有比較直觀的默認值, 并有隨 Hibernate一同分發的配置樣例hibernate.properties 來展示各種配置選項。 所需…

1.3 使用電腦測試MC20的電話語音功能

需要準備的硬件 MC20開發板 1個https://item.taobao.com/item.htm?id562661881042GSM/GPRS天線 1根https://item.taobao.com/item.htm?id531979567261IPEX接口轉SMA接口轉接線 1根https://item.taobao.com/item.htm?id531979903836GPS有源天線 1根https://item.taobao.com/i…

前端之 AJAX

AJAX參數詳細列表 參數名類型描述urlString(默認: 當前頁地址) 發送請求的地址。typeString(默認: "GET") 請求方式 ("POST" 、 "GET")。注意&#xff1a;其它 HTTP 請求方法&#xff0c;如 PUT 和 DELETE &#xff0c;但僅部分瀏覽器支持。tim…

buffer 和cache的區別

Cache&#xff1a;高速緩存&#xff0c;是位于CPU與主內存間的一種容量較小但速度很高的存儲器。 由于CPU的速度遠高于主內存&#xff0c;CPU直接從內存中存取數據要等待一定時間周期&#xff0c;Cache中保存著CPU剛用過或循環使用的一部分數據&#xff0c;當CPU再次使用該部分…

html5--1.18 div元素與布局

1.18 div元素與布局 1.元素的分類2.div元素與布局 1、元素的分類 塊元素:主要特征是會產生換行效果&#xff0c;自動與其他元素分離成兩行&#xff1b;通常可以作為容器在內部添加其他元素。已經學過的塊元素有&#xff1a; h1~h6;hr;ul;ol;p;table......... 內聯元素:不會產生…

python讀取excel表格太大怎么辦_Python:使用Openpyxl讀取大型Excel工作表

嘗試對load_workbook()類使用read_only True屬性,這會導致您獲得的工作表為IterableWroksheet,這意味著您只能迭代它們,您不能直接使用列/行號來訪問其中的單元格值.根據documentation,這將提供接近恒定的存儲器消耗.此外,您不需要關閉文件,語句將為您處理.示例 –import open…