python发送邮件详细教程 (python发送邮件html)

上次介绍Python如何发送邮件是发送纯文本的邮件,本次介绍如何发送带附件的邮件,代码都差不多,主要是如何构建带附件的代码,其主要使用到以下模块(库):

1、smtplib(smtp协议库)

2、email.utils(设置邮件账号信息,主要应用其formataddr类)

3、email.header(设置邮件标题信息,主要应用其Header类)

4、email.encoders(邮件编码格式转换,主要应用其encode_base64类)

5、email.mime.multipart(生成邮件附件对象,主要用于其MIMEMultipart类)

6、email.mime.text(发送带纯文本附件的邮件,主要应用其MIMEText类)

7、email.mime.base(发送带pdf附件的邮件,主要应用其MIMEBase类)

8、email.mime.image(发送带图片附件的邮件,主要应用其MIMEImage类)

9、email.mime.application(发送带MP3附件的邮件,主要应用其MIMEApplication类)

一、代码分析

注:发送邮件(需要开启邮箱的POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务:开启前2个即可)

如何开启可查看:Python发送邮件如何开启邮箱服务

1、导入模块(库)

import smtplib
from email.utils import formataddr
from email.header import Header
from email.encoders import encode_base64
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.application import MIMEApplication

2、设置邮箱账户信息(根据自己的邮箱设置)

my_sender = '123456789@qq.com'     # 发件人邮箱账号
my_pass = '***********'                         # 发件人邮箱密码
my_user = '123456789@qq.com'         # 收件人邮箱账号

3、利用 MIMEMultipart 类设置邮箱

# 创建实例
mp mp = MIMEMultipart("alternative")                                             # 创建一个带附件的实例(最关键)
mp['From'] = formataddr(["我爱python",my_sender])                       # 括号里的对应发件人邮箱昵称、发件人邮箱账号
mp['To'] = formataddr(["我爱python",my_user])                               # 括号里的对应收件人邮箱昵称、收件人邮箱账号
mp['Subject'] = Header("Python发送带附件的邮件","utf-8")              # 邮件的主题,也可以说是标题

# 设置邮件内容        
mp.attach(MIMEText('这是由Python发送的带附件测试邮件......','plain','utf-8'))  # 邮件正文内容

4、构建附件(txt、word、Excel、pdf、image、MP3等)

# 发送纯文本附件:传送当前目录下的 file/test1.txt 文件
with open('file/test1.txt', "rb") as fp:
    file_txt = MIMEText(fp.read(),"base64","utf-8")
    file_txt["Content-Type"] = 'application/octet-stream'
    file_txt["Content-Disposition"] = 'attachment;filename="test1.txt"'  # 这里的 filename 可以任意写,写什么名字,邮件就显示什么名字
    mp.attach(file_txt)

# 发送word格式的文件:传送当前目录下的 file/2323.docx 文件
with open('file/2323.docx', "rb") as fp:
    file_docx = MIMEApplication(fp.read())
    file_docx.add_header('Content-Disposition', f'attachment;filename="2323.docx"')
    file_docx.set_charset("utf-8")
    mp.attach(file_docx)    
    
# 发送excel格式的文件:传送当前目录下的 file/123.xls 文件
file_excel = MIMEBase("application","vnd.ms-excel")
with open('file/123.xls ', "rb") as fp:
    file_excel.set_payload(fp.read())
    encode_base64(file_excel)
    file_excel.add_header('Content-Disposition', f'attachment;filename="123.xls"')
    mp.attach(file_excel) 
    
# 发送pdf格式的文件:传送当前目录下的 file/2323.pdf 文件
with open('file/2323.pdf', "rb") as fp:
    file_pdf = MIMEBase('application', 'pdf')
    file_pdf.set_payload(fp.read())
    encode_base64(file_pdf)
    file_pdf.add_header('Content-Disposition', f'attachment;filename="2323.pdf"')
    mp.attach(file_pdf)

# 发送image格式的文件:传送当前目录下的 file/test.jpg 图片
mail_msg = """
<p>Python 邮件发送图片</p>
<p><img src="cid:image"></p>
"""   
mp.attach(MIMEText(mail_msg,'html','utf-8'))
with open('file/test.jpg','rb') as fp:
    file_image = MIMEImage(fp.read())
file_image.add_header('content-ID','<image>')
mp.attach(file_image)

# 发送audio格式的文件:传送当前目录下的 file/曾经的你.mp3 音频
file_mp3 = MIMEApplication(open('file/4545.mp3','rb').read())
file_mp3.add_header('Content-Disposition',  f'attachment;filename="4545.mp3"')
mp.attach(file_mp3)

5、定义一个函数,连接邮箱服务,登录邮箱,发送邮件

def send_mail():
    result = True
    try: 
        server = smtplib.SMTP_SSL("smtp.qq.com", 465)          # 发件人邮箱中的SMTP服务器,端口是25
        server.login(my_sender, my_pass)                       # 括号中对应的是发件人邮箱账号、邮箱密码
        server.sendmail(my_sender,[my_user,],mp.as_string())  # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
        server.quit()                                          # 关闭连接
    except Exception:                                         # 如果 try 中的语句没有执行,则会执行下面的 result=False
        result = False
    return result

6、执行函数并发送邮件,同时验证邮件是否发送成功

# 执行函数
result = send_mail()

# 判断发送成功与否
if result:
    print("邮件发送成功")
else:
    print("邮件发送失败")

7、完整代码

# 导入模块
import smtplib
from email.utils import formataddr
from email.header import Header
from email.encoders import encode_base64
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.application import MIMEApplication

# 设置邮箱信息
my_sender = '123456789@qq.com'    # 发件人邮箱账号
my_pass = '***********'                        # 发件人邮箱密码
my_user = '123456789@qq.com'       # 收件人邮箱账号,我这边发送给自己

# 创建实例
mp = MIMEMultipart("alternative")                                               # 创建一个带附件的实例:此处很关键
mp['From'] = formataddr(["我爱Python",my_sender])                   # 括号里的对应发件人邮箱昵称、发件人邮箱账号
mp['To'] = formataddr(["我爱Python",my_user])                           # 括号里的对应收件人邮箱昵称、收件人邮箱账号
mp['Subject'] = Header("Python发送带附件的邮件","utf-8")          # 邮件的主题,也可以说是标题
        
mp.attach(MIMEText('这是由Python发送的带附件测试邮件......','plain','utf-8'))  # 邮件正文内容,字体,编码格式

# 发送纯文本附件:传送当前目录下的 file/test1.txt 文件
with open('file/test1.txt', "rb") as fp:
    file_txt = MIMEText(fp.read(),"base64","utf-8")
    file_txt["Content-Type"] = 'application/octet-stream'
    file_txt["Content-Disposition"] = 'attachment;filename="test1.txt"'  # 这里的 filename 可以任意写,写什么名字,邮件就显示什么名字
    mp.attach(file_txt)

# 发送word格式的文件:传送当前目录下的 file/2323.docx 文件
with open('file/2323.docx', "rb") as fp:
    file_docx = MIMEApplication(fp.read())
    file_docx.add_header('Content-Disposition', f'attachment;filename="2323.docx"')
    file_docx.set_charset("utf-8")
    mp.attach(file_docx)    
    
# 发送excel格式的文件:传送当前目录下的 file/123.xls 文件
file_excel = MIMEBase("application","vnd.ms-excel")
with open('file/123.xls ', "rb") as fp:
    file_excel.set_payload(fp.read())
    encode_base64(file_excel)
    file_excel.add_header('Content-Disposition', f'attachment;filename="123.xls"')
    mp.attach(file_excel) 
    
# 发送pdf格式的文件:传送当前目录下的 file/2323.pdf 文件
with open('file/2323.pdf', "rb") as fp:
    file_pdf = MIMEBase('application', 'pdf')
    file_pdf.set_payload(fp.read())
    encode_base64(file_pdf)
    file_pdf.add_header('Content-Disposition', f'attachment;filename="2323.pdf"')
    mp.attach(file_pdf)

# 发送image格式的文件:传送当前目录下的 file/test.jpg 图片
mail_msg = """
<p>Python 邮件发送图片</p>
<p><img src="cid:image"></p>
"""   
mp.attach(MIMEText(mail_msg,'html','utf-8'))

with open('file/test.jpg','rb') as fp:
    file_image = MIMEImage(fp.read())
    
file_image.add_header('content-ID','<image>')
mp.attach(file_image)

# 发送audio格式的文件:传送当前目录下的 file/曾经的你.mp3 音频
file_mp3 = MIMEApplication(open('file/4545.mp3','rb').read())
file_mp3.add_header('Content-Disposition',  f'attachment;filename="4545.mp3"')
mp.attach(file_mp3)

# 定义函数:连接服务,登录邮箱,发送邮件
def send_mail():
    result = True
    try: 
        server = smtplib.SMTP_SSL("smtp.qq.com", 465)          # 发件人邮箱中的SMTP服务器,端口是25
        server.login(my_sender, my_pass)                       # 括号中对应的是发件人邮箱账号、邮箱密码
        server.sendmail(my_sender,[my_user,],mp.as_string())  # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
        server.quit()                                          # 关闭连接
    except Exception:                                         # 如果 try 中的语句没有执行,则会执行下面的 result=False
        result = False
    return result

# 执行函数
result = send_mail()

# 判断发送成功与否
if result:
    print("邮件发送成功")
else:
    print("邮件发送失败")

8、代码执行结果

python发送邮件设置多个接收邮箱,python发送邮件的模块

python发送邮件设置多个接收邮箱,python发送邮件的模块

python发送邮件设置多个接收邮箱,python发送邮件的模块

python发送邮件设置多个接收邮箱,python发送邮件的模块