SMTP發送郵件
SMTP是發送郵件的協議,Python內置對SMTP的支持,可以發送純文本郵件、HTML郵件以及帶附件的郵件。
Python對SMTP支持有smtplib和email兩個模塊:
- email負責構造郵件,
- smtplib負責發送郵件。
簡單郵件發送
先來個簡單的郵件來個入門:
首先裏用email模塊來構建一個簡單郵件文本:
form email.mime.text import MIMEText msg = MIMEText(‘Hello,send by Python‘,‘plain‘,‘utf-8‘)
構造MIMEText對象時,第一個參數就是郵件正文,第二個參數是MIME的subtype,傳入‘plain‘表示純文本,最終的MIME就是‘text/plain‘,最後一定要用utf-8編碼保證多語言兼容性。
然後利用smtplib發送出去:
import smtplib server = smtplib.SMTP(‘smtp.exmail.qq.com‘, 25) # SMTP協議默認端口是25 加密的端口為465 server.set_debuglevel(1) server.login([email protected], ‘password‘) server.sendmail([email protected], [[email protected],], msg.as_string()) # 這裏是自己給自己發郵件 server.quit()
我們用set_debuglevel(1)
login()
方法用來登錄SMTP服務器,sendmail()
方法就是發郵件,由於可以一次發給多個人,所以傳入一個list
,郵件正文是一個str
,as_string()
把MIMEText
對象變成str
。
完整的郵件發送
沒有主題,沒有發件人姓名,這......再試試,這裏我們需要把想要的信息加入到MIMEText中才可以,來吧 。試試 , 這裏我復制的是廖海峰的代碼。
_format_addr()
來格式化一個郵件地址。註意不能簡單地傳入name <[email protected]>
,因為如果包含中文,需要通過Header
msg[‘To‘]
接收的是字符串而不是list,如果有多個郵件地址,用,
分隔即可。
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 = input(‘From: ‘) password = input(‘Password: ‘) to_addr = input(‘To: ‘) smtp_server = input(‘SMTP server: ‘) 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() 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()
發送HTML郵件
在構造MIMEText
對象時,把HTML字符串傳進去,再把第二個參數由plain
變為html
就可以了:
msg = MIMEText(‘<html><body><h1>Hello</h1>‘ + ‘<p>send by <a href="http://www.python.org">Python</a>...</p>‘ + ‘</body></html>‘, ‘html‘, ‘utf-8‘)
發送帶附件的郵件
帶附件的郵件可以看做包含若幹部分的郵件:文本和各個附件本身,所以,可以構造一個MIMEMultipart
對象代表郵件本身,然後往裏面加上一個MIMEText
作為郵件正文,再繼續往裏面加上表示附件的MIMEBase
對象即可:
from email import encoders from email.header import Header from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart,MIMEBase from email.utils import parseaddr, formataddr def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, ‘utf-8‘).encode(), addr)) msg = MIMEMultipart() msg[‘From‘] = _format_addr(‘Python愛好者 <%s>‘ % [email protected]) msg[‘To‘] = _format_addr(‘管理員 <%s>‘ % [email protected]) msg[‘Subject‘] = Header(‘來自SMTP的問候……‘, ‘utf-8‘).encode() # 郵件正文是MIMEText: msg.attach(MIMEText(‘send with file...‘, ‘plain‘, ‘utf-8‘)) # 添加附件就是加上一個MIMEBase,從本地讀取一個圖片: with open(‘manage.py‘, ‘rb‘) as f: # 設置附件的MIME和文件名,這裏是png類型: mime = MIMEBase(‘text‘, ‘py‘, filename=‘manage.py‘) # 加上必要的頭信息: mime.add_header(‘Content-Disposition‘, ‘attachment‘, filename=‘manage.py‘) mime.add_header(‘Content-ID‘, ‘<0>‘) mime.add_header(‘X-Attachment-Id‘, ‘0‘) # 把附件的內容讀進來: mime.set_payload(f.read()) # 用Base64編碼: encoders.encode_base64(mime) # 添加到MIMEMultipart: msg.attach(mime) import smtplib server = smtplib.SMTP(‘smtp.exmail.qq.com‘, 25) # SMTP協議默認端口是25 加密的端口為465 server.set_debuglevel(1) server.login([email protected], [email protected]) server.sendmail([email protected], [[email protected],], msg.as_string()) server.quit()
待續。。。
SMTP發送郵件