原文鏈接:
https://www.jianshu.com/p/369ec15bfe22
本文介紹python發送郵件模塊smtplib以及相關MIME模塊。
smtplib用於生成郵件發送的代理,發送郵件前需要通過MIMEText構造郵件內容。
發送純文本郵件
下面是個發送純文本郵件的例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
import smtplib from email.mime.text import MIMEText msg_from='XXXXX@163.com' passwd='XXXXX' msg_to='XXXXX@qq.com' subject="python郵件測試" content="這是我使用python smtplib及email模塊發送的郵件"
msg = MIMEText(content) msg['Subject'] = subject msg['From'] = msg_from msg['To'] = msg_to try: |
MIMEText實例化一個郵件對象,內容為content,對於郵件標題Subject,發件人From,以及收件人To
需要以字典形式指出,或者通過add_header(下文會給出)添加,否則對方看不到這些信息。
想要通過smtp發送郵件,需要打開指定郵箱的smtp協議,以及設置smtp授權密碼。我設置的是163郵箱的。


設置好密碼后,將上述代碼中的passwd改為你的密碼,msg_from改為你的郵箱。smtplib可以通過SMTP_SSL
發送,也可以采用普通形式直接初始化,對應的兩個參數分別是授權的smtp服務器地址和端口號,因為我
設置的是163的,所以使用smtp.163.com服務器地址,端口號和服務器地址讀者可以自己去查。通過生成的
smtp實例,一次調用login,sendemail就可以發送了。最后記得調用quit退出。
發送一封純文本郵件,看一下效果

我們發現發件人標題顯示的只有郵箱地址,沒有昵稱,可以采用parseaddr和formataddr對發件人信息完善。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr))
import smtplib from email.header import Header from email.mime.text import MIMEText from email.utils import parseaddr, formataddr
msg_from='XXXXX@163.com' passwd='XXXXX' msg_to='XXXXX@qq.com' receivers = ['XXXXX@qq.com'] subject="python郵件測試" content="這是我使用python smtplib及email模塊發送的郵件"
msg = MIMEText(content,'plain','utf-8') msg['Subject'] = Header(subject,'utf-8').encode() msg['From'] = _format_addr('戀戀風辰 <%s>' %msg_from) msg['To'] = msg_to
try: |
這樣可以看到發件人的昵稱了。我設置的是戀戀風辰。Header函數的作用是防止中文亂碼。
Header對字符串按照utf-8方式編碼。MIMEText中參數plain表示純文本,utf-8表示純文本
的編碼方式。

發送html郵件
發送html郵件和之前發送純文本類似,只需要將plain變為html,即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr))
import smtplib from email.header import Header from email.mime.text import MIMEText from email.utils import parseaddr, formataddr msg_from = 'XXXXXX@163.com' passwd = 'XXXXX' msg_to='XXXXXX@qq.com' receivers = ['XXXXXX@qq.com'] subject = 'python郵件測試html' content = '<html><body><h1>Hello</h1>' +\ '<p>send by <a href="http://www.python.org">Python</a>...</p>'
msg = MIMEText(content, 'html', 'utf-8') msg['Subject'] = Header(subject, 'utf-8').encode() msg['From'] = _format_addr('戀戀風辰 <%s>' %msg_from) msg['To'] = msg_to
try: s = smtplib.SMTP("smtp.163.com",25) s.login(msg_from, passwd) s.sendmail(msg_from, receivers, msg.as_string()) print('發送成功') except smtplib.SMTPException as e: print('發送失敗') finally: s.quit()
|
看看效果:

發送帶附件的郵件
發送帶附件的郵件,和之前不同,需要通過MIMEMultipart創建郵件實例,
然后將文本,附件等通過attach方法綁定到郵件實例上,然后一起發送。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
import smtplib import email from email.header import Header from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.utils import parseaddr, formataddr from email.mime.base import MIMEBase
def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr))
msg_from = 'XXXXX@163.com' passwd = 'XXXXX' msg_to='XXXXXX@qq.com' receivers = ['XXXX@qq.com'] subject = 'python郵件測試附件' content = '<html><body><h1>Hello</h1>' +\ '<p>send by <a href="http://www.python.org">Python</a>...</p>'
|
MIMEMultipart創建郵件實例msg,將收件人,發件人,主題設置到msg上。
然后通過MIMEText創建html文本內容,調用msg.attach方法將文本內容綁定
到郵件上。同樣的道理,打開一個圖片,通過MIMEBase創建一個附件實例,
設置文件名,文件類型,綁定的id等等,最后通過set_payload加載到附件,
然后msg.attach綁定到郵件實例上。后面的發送流程和之前一樣。
看看效果:

發送帶圖片的html郵件
想要在html中添加圖片,並且在郵件正文中顯示,只需要在html文本中引用
圖片id即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
import smtplib from email.header import Header from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.utils import parseaddr, formataddr from email.mime.base import MIMEBase from email.mime.image import MIMEImage
def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr))
msg_from = 'XXXXXXXXXXXX@163.com' passwd = 'XXXXX' msg_to='XXXXXXXXX@qq.com' receivers = ['XXXXXXXXXX@qq.com'] subject = 'python郵件測試附件' content = '<b>Some <i>HTML</i> text</b> and an image.<br><img src="cid:image1"><br>good!'
|
mime.add_header(‘Content-ID’,'<image1>'
) 設置圖片id為image1,
在html中引用image1就可以在郵件中文中顯示圖片了。
通過<img src="cid:image1">
方式進行引用。
Messge類的繼承和派生關系
1 2 3 4 5 6 7
|
Message +- MIMEBase +- MIMEMultipart +- MIMENonMultipart +- MIMEMessage +- MIMEText +- MIMEImage
|
MIMEBase繼承於Message,MIMEMultipart繼承於MIMEBase。
用MIMEText發送多種附件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
import smtplib from email.mime.text import MIMEText from email.header import Header from email.mime.multipart import MIMEMultipart from email.utils import parseaddr, formataddr import os
def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr))
msg_from = 'XXXXXXXXX@163.com' passwd = 'XXXXXXXXXXX' msg_to='XXXXXXXXX@qq.com' receivers = ['XXXXXXXXXXX@qq.com'] subject = 'python郵件測試附件' content = '多種附件'
|
大體原理和之前一樣,通過MIMEText可以實現多種附件的發送。
注意格式改為base64,編碼用utf-8,可以實現多種附件發送。
效果如下:

通過MIMEApplication發送多種附件
同樣可以通過MIMEApplication發送多種附件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
import smtplib from email.mime.text import MIMEText from email.mime.application import MIMEApplication from email.header import Header from email.mime.multipart import MIMEMultipart from email.utils import parseaddr, formataddr import os
def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr))
msg_from = 'xxxxxxxxx@163.com' passwd = 'xxxxxxxxxx' msg_to='xxxxxxxxxxx@qq.com' receivers = ['xxxxxxxxx@qq.com'] subject = 'python郵件測試附件' content = '多種附件'
|
效果和之前的一樣,這就是python中利用smtplib和MIME構造郵件發送的案例。