众所周知SMTP是发送邮件的协议,POP3是接收邮件的协议

    因为在python中内置了对SMTP的支持,所以通过它可以发送纯文本的邮件,html邮件和带附件的邮件。

    在python中支持SMTP的模块有email和smtplib,其中email负责构造邮件,smtplib负责发送邮件。

发送纯文本邮件one:

from email.mime.text import MIMEText
import smtplib

# 1参: 邮件正文 2参: subtype,plan代表的是纯文本 3参:编码格式
msg = MIMEText('hello,from Gt futures...','plan','utf-8')
# 打印后会发现正文数据是加密的
# print(msg)
# 将数据转换成字符串格式
# print(msg.as_string())

# 发送者帐号密码与接受者帐号
from_addr = 'your email @163.com'
pwd = 'your passwd'
to_addr = 'her email @qq.com'
# smtp服务器地址,指的是代发的服务器地址。就是邮箱的服务器地址
smtp_server = 'smtp.163.com' 
# 网易163 的SMTP服务器地址,因为我使用的是163邮箱所以要使用163的stmp协议
# 默认无ssl的端口为25
server = smtplib.SMTP(smtp_server,25)

server.set_debuglevel(1) # 可以打印出和SMTP服务器交互的信息
server.login(from_addr,pwd) # 登录STMP服务器
server.sendmail(from_addr,to_addr,msg.as_string()) # 发送: 发送者,接受者,正文
# 注意这里的to_addr 可以是一个列表,用来群发消息
server.quit() # 关闭

在上面代码运行时可能会554的错误。为什么我说可能呢?因为有些不同的stmp服务器的要求不同。

发送纯文本邮件two:

from email.mime.text import MIMEText
import smtplib

from email.utils import parseaddr,formataddr
from email.header import Header
from_addr = 'your email@163.com'
pwd = 'your passwd'
to_addr = 'her email@foxmail.com'
# smtp服务器地址,指的是代发的服务器地址。就是邮箱的服务器地址
smtp_server = 'smtp.163.com' # 网易163 的SMTP服务器地址

def _format_addr(s):
    '''格式化邮件地址'''
    # 可以将发件人名字和帐号分开 比如 python爱好者<951428148@qq.com> 分成python爱好者,951428148@qq.com
    name,addr = parseaddr(s)
    # Header会将中文信息进行编码,formataddr格式化,将名字和帐号结合: =?utf-8?b?5aSn6b6E5Lit5bm05Lq6?= <17635035787@163.com>
    return formataddr((Header(name,'utf-8').encode(),addr))
# 正文,1参: 邮件正文 2参: subtype,plan代表的是纯文本 3参:编码格式
msg = MIMEText('为什么什么都没有','plan','utf-8')
# 发送者
msg['From'] = _format_addr('大龄中年人<%s>'%from_addr)
# 接收者
msg['To'] = _format_addr('管理员<%s>'%to_addr)
# 标题
msg['Subject'] = Header('来自Smtp的问候','utf-8').encode()
# 默认无ssl的端口为25,启动SMTP服务器
server = smtplib.SMTP(smtp_server,25)
# 可以打印出和SMTP服务器交互的信息
server.set_debuglevel(1)
# 帐号登录
server.login(from_addr,pwd)
# 发送邮件
server.sendmail(from_addr,to_addr,msg.as_string())
#关闭
server.quit()

在这块代码中我增加了一个函数,它是用来将邮件地址格式化。

    parseaddr 这个方法会将传入的数据进行解析,拆分成一个用户名一个邮件地址。

    header会将中文数据进行编码。

    formatadrr就是将俩个信息进行格式化,将编码后的用户名和邮件地址进行联合。

解释一下msg添加的键值对,此时的msg是一个邮件类型的数据,通过给他配置合适的键来添加消息头的信息:

    From   代表  发送者

    To  代表  接收者

    Subject  代表  标题

 

发送带有HTML效果的邮件:

from email.mime.text import MIMEText
import smtplib

from email.utils import parseaddr,formataddr
from email.header import Header
from_addr = 'your email@163.com'
pwd = 'your passwd'
to_addr = 'her email@foxmail.com'
# smtp服务器地址,指的是代发的服务器地址。就是邮箱的服务器地址
smtp_server = 'smtp.163.com' # 网易163 的SMTP服务器地址

def _format_addr(s):
    '''格式化邮件地址'''
    name,addr = parseaddr(s)
    return formataddr((Header(name,'utf-8').encode(),addr))

strs = '''<html><body><h1>Hello word</h1><p>测试</p></body></html>'''
# 正文,1参: 邮件正文 2参: subtype,html代表的是html类型 3参:编码格式
msg = MIMEText(strs,'html','utf-8')
# 发送者
msg['From'] = _format_addr('大龄中年人<%s>'%from_addr)
# 接收者
msg['to'] = _format_addr('管理员<%s>'%to_addr)
# 标题
msg['Subject'] = Header('来自Smtp的问候','utf-8').encode()
# 默认无ssl的端口为25,启动SMTP服务器
server = smtplib.SMTP(smtp_server,25)
# 可以打印出和SMTP服务器交互的信息
server.set_debuglevel(1)
# 帐号登录
server.login(from_addr,pwd)
# 发送邮件
server.sendmail(from_addr,to_addr,msg.as_string())
#关闭
server.quit()

其实发送html和纯文本的方法大致相同,只需要更改一些配置就好了。

    将MIMEText的前俩个参数换成相应的html数据和html,就ok了

 

发送带有附件的邮件:

import os
from email import encoders
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
import smtplib
from email.utils import parseaddr,formataddr
from email.header import Header

from_addr = 'your email@163.com'
pwd = 'your passwd'
to_addr = 'her email@foxmail.com'
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('大龄中年人<%s>'%from_addr)
# 接收者
msg['to'] = _format_addr('管理员<%s>'%to_addr)
# 标题
msg['Subject'] = Header('请你接收图片','utf-8').encode()
# 邮件正文
strs = '''<html><body><h1>Hello word</h1><p>测试</p></body></html>'''
text_msg = MIMEText(strs,'html','utf-8')
# 将正文添加到MIMEultipart
msg.attach(text_msg)
# 添加附件
with open(os.getcwd()+'\\test.png','rb') as  f:
    # 设置附件的MIME和文件名字
    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
    mime.set_payload(f.read())
    # 使用Base64编码
    encoders.encode_base64(mime)
    # 将附件添加到MIMEultipart
    msg.attach(mime)
# 默认无ssl的端口为25,启动SMTP服务器
server = smtplib.SMTP(smtp_server,25)
# 可以打印出和SMTP服务器交互的信息
server.set_debuglevel(1)
# 帐号登录
server.login(from_addr,pwd)
# 发送邮件
server.sendmail(from_addr,to_addr,msg.as_bytes())
#关闭
server.quit()

与之前发送正文添加From To这些数据类似 ,不过它是通过MIMEMultipart来代表邮件本身,MIMEText作为邮件正文,MIMEBase代表附件。

将附件写入到正文当中,只需要在html进行调用就好了,比如将图片写入到正文:

strs = '''<html><body><h1>Hello word</h1><p><img src="cid:0"></p></body></html>'''

只需要在html当中添加一个img标签就好。