一、發(fā)送普通郵件
固定格式:
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import smtplib
def send_msg(from_addr, password, to_addr):
from_addr = from_addr
password = password
to_addr = to_addr
smtp_server = "smtp.163.com"
# 格式化一個郵件地址
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
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()
二、發(fā)送HTML郵件
如果我們要發(fā)送HTML郵件,而不是普通的純文本文件怎么辦?方法很簡單,在構(gòu)造MIMEText對象時,把HTML字符串傳進(jìn)去,再把第二個參數(shù)由plain變?yōu)閔tml就可以了
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import smtplib
def send_msg(from_addr, password, to_addr):
from_addr = from_addr
password = password
to_addr = to_addr
smtp_server = "smtp.163.com"
# 格式化一個郵件地址
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
msg = MIMEText('<html><body><h1>Hello</h1>' +
'<p>send by <a +
'</body></html>', 'html', '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()
三、發(fā)送附件郵件
如果Email中要加上附件怎么辦?帶附件的郵件可以看做包含若干部分的郵件:文本和各個附件本身,所以,可以構(gòu)造一個MIMEMultipart對象代表郵件本身,然后往里面加上一個MIMEText作為郵件正文,再繼續(xù)往里面加上表示附件的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
import smtplib
def send_msg(from_addr, password, to_addr):
from_addr = from_addr
password = password
to_addr = to_addr
smtp_server = "smtp.163.com"
# 格式化一個郵件地址
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
# 郵件對象:
msg = MIMEMultipart()
msg['From'] = _format_addr('Python愛好者 <%s>' % from_addr)
msg['To'] = _format_addr('管理員 <%s>' % to_addr)
msg['Subject'] = Header('來自SMTP的問候……', 'utf-8').encode()
# 郵件正文是MIMEText:
msg.attach(MIMEText('send with file...', 'plain', 'utf-8'))
# 添加附件就是加上一個MIMEBase,從本地讀取一個圖片:
with open('/Users/wangjifei/PycharmProjects/flask_demo/屏幕快照 2018-12-22 下午6.05.48.png', 'rb') as f:
# 設(shè)置附件的MIME和文件名,這里是png類型:
mime = MIMEBase('image', 'png', filename='test.png')
# 加上必要的頭信息:
mime.add_header('Content-Disposition', 'attachment', filename='test.png')
mime.add_header('Content-ID', '<0>')
mime.add_header('X-Attachment-Id', '0')
# 把附件的內(nèi)容讀進(jìn)來:
mime.set_payload(f.read())
# 用Base64編碼:
encoders.encode_base64(mime)
# 添加到MIMEMultipart:
msg.attach(mime)
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()
四、發(fā)送圖片
如果要把一個圖片嵌入到郵件正文中怎么做?直接在HTML郵件中鏈接圖片地址行不行?答案是,大部分郵件服務(wù)商都會自動屏蔽帶有外鏈的圖片,因為不知道這些鏈接是否指向惡意網(wǎng)站。
要把圖片嵌入到郵件正文中,我們只需按照發(fā)送附件的方式,先把郵件作為附件添加進(jìn)去,然后,在HTML中通過引用src="cid:0"就可以把附件作為圖片嵌入了。如果有多個圖片,給它們依次編號,然后引用不同的cid:x即可
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
import smtplib
def send_msg(from_addr, password, to_addr):
from_addr = from_addr
password = password
to_addr = to_addr
smtp_server = "smtp.163.com"
# 格式化一個郵件地址
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
# 郵件對象:
msg = MIMEMultipart()
msg['From'] = _format_addr('Python愛好者 <%s>' % from_addr)
msg['To'] = _format_addr('管理員 <%s>' % to_addr)
msg['Subject'] = Header('來自SMTP的問候……', 'utf-8').encode()
# 郵件正文是MIMEText:
msg.attach(MIMEText('<html><body><h1>Hello</h1>' +
'<p><img src="cid:0"></p>' +
'</body></html>', 'html', 'utf-8'))
# 添加附件就是加上一個MIMEBase,從本地讀取一個圖片:
with open('/Users/wangjifei/PycharmProjects/flask_demo/屏幕快照 2018-12-22 下午6.05.48.png', 'rb') as f:
# 設(shè)置附件的MIME和文件名,這里是png類型:
mime = MIMEBase('image', 'png', filename='test.png')
# 加上必要的頭信息:
mime.add_header('Content-Disposition', 'attachment', filename='test.png')
mime.add_header('Content-ID', '<0>')
mime.add_header('X-Attachment-Id', '0')
# 把附件的內(nèi)容讀進(jìn)來:
mime.set_payload(f.read())
# 用Base64編碼:
encoders.encode_base64(mime)
# 添加到MIMEMultipart:
msg.attach(mime)
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和Plain格式
如果我們發(fā)送HTML郵件,收件人通過瀏覽器或者Outlook之類的軟件是可以正常瀏覽郵件內(nèi)容的,但是,如果收件人使用的設(shè)備太古老,查看不了HTML郵件怎么辦?
辦法是在發(fā)送HTML的同時再附加一個純文本,如果收件人無法查看HTML格式的郵件,就可以自動降級查看純文本郵件。
利用MIMEMultipart就可以組合一個HTML和Plain,要注意指定subtype是alternative:
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
import smtplib
def send_msg(from_addr, password, to_addr):
from_addr = from_addr
password = password
to_addr = to_addr
smtp_server = "smtp.163.com"
# 格式化一個郵件地址
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
# 郵件對象:
msg = MIMEMultipart('alternative')
msg['From'] = _format_addr('Python愛好者 <%s>' % from_addr)
msg['To'] = _format_addr('管理員 <%s>' % to_addr)
msg['Subject'] = Header('來自SMTP的問候……', 'utf-8').encode()
# 郵件正文是MIMEText:
msg.attach(MIMEText('hello', 'plain', 'utf-8'))
msg.attach(MIMEText('<html><body><h1>Hello</h1></body></html>', 'html', 'utf-8'))
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()