python之smtplib邮件发送

虽然一般自动化持续集成中都用Jenkins来发送邮件,但了解掌握一下python的smtplib模块发送邮件也是必要的。

先明确一下发邮件的步骤:

1.确定邮件服务商:网易、qq等

2.登录邮箱:用户名/密码(密码一般是授权码)

3.编辑邮件主题、内容、附件

4.发送邮件

最简单的实现:

server = smtplib.SMTP('smtp.163.com',25)
server.login(emailname,emailpwd)    # 登录
# 邮件内容
msg = '''\\From: xia
           Subject: Hello World           
           This is a test '''
# 发送邮件
server.sendmail(emailname,'[email protected]',msg)

  如上代码创建一个实例化对象server,调用SMTP类下的login方法,采用163邮件服务,默认端口是25,emailname和emailpwd分别为发送邮件的用户名和授权码。

实际在发邮件的时候,我们通常使用加密模式。简单的两种加密方法:

1.tls模式加密

server = smtplib.SMTP('smtp.163.com',25)

server.login(emailname,emailpwd)    # 登录
context = ssl.create_default_context()
server.starttls(context=context)
# 邮件内容 msg = '''\\ From: xia 
             Subject: Hello World 
             This is a test ''' 
# 发送邮件 
server.sendmail(emailname,'[email protected]',msg)
server.quit()

2.ssl加密,默认加密端口是465

server = smtplib.SMTP_SSL('smtp.163.com',465)
server.login(emailname,emailpwd)    # 登录
# 邮件内容
msg = '''\\
             From: xia
             Subject: Hello World           
             This is a test '''
# 发送邮件
server.sendmail(emailname,'[email protected]',msg)
server.quit()

创建server后,要记得quit关闭。也可以使用上下文管理器,防止忘记关闭邮件:

with smtplib.SMTP_SSL('smtp.163.com',465) as server:
    server.login(emailname,emailpwd)    # 登录
    # 加密1. tls模式
    server.starttls(context=context)
    # 邮件内容
    msg = '''\\
             From: xia
             Subject: Hello World           
             This is a test '''
    # 发送邮件
    server.sendmail(emailname,'[email protected]',msg)

 但是实际应用中,不可能会发送这么简单的邮件。我们需要丰富邮件主题、内容和附件。

这就需要引入两个模块:

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

 首先创建一个带附件的实例,设置邮件主题,from,to信息:

msg_total = MIMEMultipart()
msg_total['subject'] = Header(self.subject,'utf-8')
msg_total['From'] = emailname
msg_total['To'] = self.tolist

  

 添加邮件正文内容,这里添加html格式的内容:

content = '''<p style="color:red">你好,我是一份测试邮件。</p>'''
msg_total.attach(MIMEText(content, 'html','utf-8'))

  

 也可以读取某个文件内容作为邮件正文:

with open(file, 'rb') as f:
    content = f.read()
    msg_total.attach(MIMEText(content, 'html', 'utf-8'))

  

 添加附件之前,首先要获取想要发送的附件:

with open(file, 'rb') as f:
    mail_attach = f.read()
    att = MIMEText(mail_attach, 'base64', 'utf-8')
    att["Content-Type"] = 'application/octet-stream'
    # 这里的filename可以任意写,写什么名字,邮件中显示什么名字
    att["Content-Disposition"] = 'attachment; filename="测试报告"'
    msg_total.attach(att)

  

 上面邮件正文和附件文件都是写死的,一般在应用中,我们可以获取当前最新的测试执行报告作为附件:

file = os.listdir(report_path)  # 列出目录的下所有文件和文件夹
file.sort(key=lambda fn: os.path.getmtime(report_path + "\\" + fn))  # 按时间排序
file_name = file[-1]
file_new = os.path.join(report_path, file[-1])  # 获取最新的文件保存到file_new

# 添加文件内容作为正文模块
with open(file_new, 'rb') as f:
    content = f.read()
    msg_total.attach(MIMEText(content, 'html', 'utf-8'))

# 附件模块
with open(file_new, 'rb') as f:
    mail_attach = f.read()
    att = MIMEText(mail_attach, 'base64', 'utf-8')
    att["Content-Type"] = 'application/octet-stream'
    # 这里的filename可以任意写,写什么名字,邮件中显示什么名字
    att["Content-Disposition"] = 'attachment; filename="{}"'.format(file_name)
    msg_total.attach(att)

  

 整合以上邮件主题、内容、附件,并封装成一个类,便于后续调用。完整代码如下:

import smtplib
from python15.class_email.conf import *
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
import os

class MyEmail:

    def __init__(self,host,port,tolist,subject,content=None):
        self.host = host    #邮件服务地址
        self.port = port    # 邮件服务端口
        self.tolist = tolist # 接收人
        self.subject = subject  # 邮件主题
        self.content = content  # 邮件内容

    def send_email(self):

        # 总的邮件内容,创建一个带附件的实例
        msg_total = MIMEMultipart()
        msg_total['subject'] = Header(self.subject,'utf-8')
        msg_total['From'] = emailname
        msg_total['To'] = self.tolist

        file = os.listdir(report_path)  # 列出目录的下所有文件和文件夹
        file.sort(key=lambda fn: os.path.getmtime(report_path + "\\" + fn))  # 按时间排序
        file_name = file[-1]
        file_new = os.path.join(report_path, file[-1])  # 获取最新的文件保存到file_new

        # 添加文件内容作为正文模块
        with open(file_new, 'rb') as f:
            content = f.read()
            msg_total.attach(MIMEText(content, 'html', 'utf-8'))

        # 附件模块
        with open(file_new, 'rb') as f:
            mail_attach = f.read()
            att = MIMEText(mail_attach, 'base64', 'utf-8')
            att["Content-Type"] = 'application/octet-stream'
            # 这里的filename可以任意写,写什么名字,邮件中显示什么名字
            att["Content-Disposition"] = 'attachment; filename="{}"'.format(file_name)
            msg_total.attach(att)

        try:
            self.server = smtplib.SMTP_SSL(self.host, self.port)
            self.server.login(emailname, emailpwd)
            self.server.sendmail(emailname, self.tolist, msg_total.as_string())
            print("邮件发送成功")
        except smtplib.SMTPException as e:
            print("Error: 无法发送邮件",e)
        finally:
            self.server.quit()

  

猜你喜欢

转载自www.cnblogs.com/Dahlia/p/10639916.html