SMTP是發送郵件的協議,Python內置對SMTP的支持,可以發送純文本郵件、HTML郵件以及帶附件的郵件。
Python對SMTP支持有smtplib
和email
兩個模塊,email
負責構造郵件,smtplib
負責發送郵件。
普通正文郵件:
#/usr/bin/env python #coding=utf-8 from email import encoders from email.header import Header from email.mime.text import MIMEText from email.utils import parseaddr, formataddr import smtplib def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr)) from_addr = 'zy5724@163.com' password = 'xxxxx' to_addr = 'scottcho@qq.com' smtp_server = 'smtp.163.com' msg = MIMEText('hello, send by Python...', 'plain', 'utf-8') msg['From'] = _format_addr('Python愛好者 <%s>' % from_addr) msg['To'] = _format_addr('管理員 <%s>' % to_addr) msg['Subject'] = Header('來自SMTP的問候……', 'utf-8').encode() try: server = smtplib.SMTP(smtp_server, 25) # server.set_debuglevel(1) server.login(from_addr, password) server.sendmail(from_addr, [to_addr], msg.as_string()) server.quit() print 'send OK' except Exception, e: print str(e)
注意到構造MIMEText
對象時,第一個參數就是郵件正文,第二個參數是MIME的subtype,傳入'plain'
表示純文本,最終的MIME就是'text/plain'
,最后一定要用utf-8
編碼保證多語言兼容性。
我們用set_debuglevel(1)
就可以打印出和SMTP服務器交互的所有信息。SMTP協議就是簡單的文本命令和響應。login()
方法用來登錄SMTP服務器,sendmail()
方法就是發郵件,由於可以一次發給多個人,所以傳入一個list
,郵件正文是一個str
,as_string()
把MIMEText
對象變成str
。
收到的郵件:
帶有附件的郵件:
#/usr/bin/env python # coding: utf-8 from email import encoders from email.header import Header from email.mime.text import MIMEText from email.MIMEBase import MIMEBase from email.utils import parseaddr, formataddr from email.mime.multipart import MIMEMultipart import smtplib def _format_addr(s): name, addr = parseaddr(s) return formataddr(( \ Header(name, 'utf-8').encode(), \ addr.encode('utf-8') if isinstance(addr, unicode) else addr)) from_addr = 'zy5724@163.com' password = 'xxxx' to_addr = 'scottcho@qq.com' smtp_server = 'smtp.163.com' # 郵件對象: msg = MIMEMultipart() msg['From'] = _format_addr(u'張三 <%s>' % from_addr) msg['To'] = _format_addr(u'管理員 <%s>' % to_addr) msg['Subject'] = Header(u'來自SMTP的問候……', 'utf-8').encode() # 郵件正文是MIMEText: msg.attach(MIMEText('send with file...', 'plain', 'utf-8')) # 添加附件就是加上一個MIMEBase att1 = MIMEText(open('/python/new.txt', 'rb').read(), 'base64', 'utf-8') att1["Content-Type"] = 'application/octet-stream' att1["Content-Disposition"] = 'attachment; filename="new.txt"' msg.attach(att1) #再添加一個圖片附件 with open('/python/Koala.jpg', 'rb') as f: att2 = MIMEBase('image', 'jpg', filename='Koala.jpg') att2.add_header('Content-Disposition', 'attachment', filename='Koala.jpg') att2.add_header('Content-ID', '<0>') att2.set_payload(f.read()) encoders.encode_base64(att2) msg.attach(att2) server = smtplib.SMTP(smtp_server, 25) server.set_debuglevel(1) server.login(from_addr, password) server.sendmail(from_addr, [to_addr], msg.as_string()) server.quit()
我們編寫了一個函數_format_addr()
來格式化一個郵件地址。注意不能簡單地傳入name <addr@example.com>
,因為如果包含中文,需要通過Header
對象進行編碼。
結果:
使用開源的yagmail發送郵件
yagmail底層依然使用smtplib和email模塊,但是它提供了更加Pythonic的接口。
安裝: pip install yagmail
查看郵件: