基于SMTP协议的电子邮件客户端程序
电子邮件的完整传输过程:
发件人 -> MUA -> MTA -> MTA -> 若干个MTA -> MDA <- MUA <- 收件人
MUA:邮件用户代理
MTA:邮件传输代理
MDA:邮件投递代理
# -*- coding: utf-8 -*-
"""
Created on Tue Dec 11 15:40:02 2018
@author: yufeng
"""
'''
电子邮件的完整传输过程:
发件人 -> MUA -> MTA -> MTA -> 若干个MTA -> MDA <- MUA <- 收件人
Python对SMTP支持有smtplib和email两个模块,
eamil负责构造邮件,smtplib负责发送邮件
邮件主题、如何显示发件人、收件人等信息并不是通过SMTP协议发给MTA,
而是包含在发给MTA的文本中的,所以,我们必须把From、To和Subject添加到MIMEText中,
才是一封完整的邮件
'''
import smtplib
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
# 输入Email地址 和 密码; 收件人地址;SMTP服务器地址
from_addr = input('From: ')
password = input('Password: ')
to_addr = input('To: ')
smtp_server = 'smtp.sina.com'
smtp_port = 25
# 设置收发邮件人,邮件主题,邮件正文
# 参数分别代表 邮件正文; MIME的subtype, 'plan'表示纯文本,最终是'text/plain'
# 第三个参数是编码格式,保证多种语言的兼容性
# from:XXX@sina.com 这里必须加上发送邮箱地址,
# 参考: https://blog.csdn.net/weixin_36394146/article/details/81268466
#msg = MIMEText('from:fzhiy270@sina.comhello, send by Python...', 'plain', 'utf-8')
#msg = MIMEText('<html><body><h1>Hello</h1>' +
# '<p>send by <a href="http://www.python.org">Python</a>...</p>' +
# '</body></html>', 'html', 'utf-8')
# 邮件对象:
msg = MIMEMultipart()
# 邮件正文是MIMEText:
#msg.attach(MIMEText('send with file...', 'plain', 'utf-8'))
msg.attach(MIMEText('<html><body><h1>Hello</h1>' +
'<p><img src="cid:0"></p>' +
'</body></html>', 'html', 'utf-8'))
# 添加附件就是加上一个MIMEBase,从本地读取一个图片:
with open(r'F:\workSpaces\PyCodes\spyder-py3\test.png', 'rb') as f:
# 设置附件的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')
# 把附件的内容读进来:
mime.set_payload(f.read())
# 用Base64编码:
encoders.encode_base64(mime)
# 添加到MIMEMultipart:
msg.attach(mime)
msg['From'] = _format_addr('fzhiy270 <%s>' % from_addr)
msg['To'] = _format_addr('接收邮件测试账号 <%s>' % to_addr)
msg['Subject'] = Header('基于SMTP协议发送邮件的测试', 'utf-8').encode()
# SMTP协议的默认端口号为25, SMTP协议是明文口令
server = smtplib.SMTP(smtp_server, smtp_port)
# 在创建SMTP对象后,立刻调用starttls()方法,就创建了安全连接
server.starttls()
server.set_debuglevel(1) # 打印出和SMTP服务器交互的所有信息
server.login(from_addr, password)
# 邮件正文是一个str,as_string()把MIMEText对象变成str。
server.sendmail(from_addr, [to_addr], msg.as_string())
server.quit()
完整邮件接收:
HTML邮件接收:
发送附件的邮件接收:
发送图片:
小结
使用Python的smtplib发送邮件十分简单,只要掌握了各种邮件类型的构造方法,正确设置好邮件头,就可以顺利发出。
构造一个邮件对象就是一个Messag
对象,如果构造一个MIMEText
对象,就表示一个文本邮件对象,如果构造一个MIMEImage
对象,就表示一个作为附件的图片,要把多个对象组合起来,就用MIMEMultipart
对象,而MIMEBase
可以表示任何对象。它们的继承关系如下:
Message
+- MIMEBase
+- MIMEMultipart
+- MIMENonMultipart
+- MIMEMessage
+- MIMEText
+- MIMEImage
这种嵌套关系就可以构造出任意复杂的邮件。你可以通过email.mime文档查看它们所在的包以及详细的用法。
如果你运行程序后没有找到发送后的邮件,可以去垃圾邮件看看