Python 发送带附件的电子邮件

使用Python smtplib和email模块发送带附件的电子邮件

导入必要的库

首先导入需要使用到的 Python 库。

import smtplib, ssl
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

以上的五个库分别负责:

  • smtplib : 提供了一个客户端对象,可以用于向 SMTP 服务器发送邮件。
  • ssl : 这个模块提供了加密链接,对于某些邮件服务商(比如Gmail)是必需的。
  • encoders : 这个模块处理基础的格式转换,在纯文本数据与二进制流之间进行转换,主要作用为编码消息正文及其部分。
  • MIMEBase : 它提供了创建、读取、写入、操控MIME 正文的功能。
  • MIMEMultipart: 这个类用于创造复合类型的 MIME 文档(multipart/*),可能包含多种属性,如图像,附件等。
  • MIMEText: 用于保存普通文本内容的 MIME 对象。

构建 MIMEMultipart 邮件主体

构建 MIMEMultipart 对象,并设置相关属性—发件人(sender_email),收件人(receiver_email),主题(subject)等信息:

sender_email = "[email protected]"
receiver_email = "[email protected]"

message = MIMEMultipart()
message["Subject"] = "这是邮件主题、"
message["From"] = sender_email 
message["To"] = receiver_email 

然后添加邮件文字内容至message:

body = "这是邮件正文"
message.attach(MIMEText(body, "plain"))

处理附件

首先需要打开所需要附件文件,并且以"rb"(只读二进制)形式读取其内容:

file = "Document.pdf"
with open(file, "rb") as attachment:
    part = MIMEBase("application", "octet-stream")
    part.set_payload(attachment.read())

上面读取了待附件的PDF文档并设置了 payload,那么下一步就是对读取的pdf附件内容进行编码处理了。

encoders.encode_base64(part)
part.add_header(
    "Content-Disposition",
    f"attachment; filename= {file}",
)
message.attach(part)

调用 message 的 attach 方法将这个附件添加到邮件正文中。

向SMTP服务器发送电子邮件

连接到SMTP服务器并发送邮件。

context = ssl.create_default_context()

with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
    server.login(sender_email, password)
    server.sendmail(
        sender_email, receiver_email, message.as_string()
    )

在真实的项目中,可以利用函数封装。

注意此例中使用了 Gmail SMTP服务,如果您想采用其他服务,请查阅相应文档获取SMTP服务器名和SSL端口。

腾讯企业邮箱发送附件实例

#Create by:zhangyongze
#为什么不问问神奇的海螺呢丶
# smtplib 用于邮件的发信动作
import smtplib
# email 用于构建邮件内容
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# 构建邮件头
from email.header import Header
import datetime
import os

#获取创建时间最新的文件
def get_latest_file(path):
    # 获取目录下所有文件的列表 (绝对路径)
    files = [os.path.join(path, file) for file in os.listdir(path)]
    # 使用文件创建时间作为关键字排序,最新的文件在最后
    files.sort(key=lambda x: os.path.getctime(x))
    # 返回文件名(带路径)
    latest_file_full_path = files[-1]
    return latest_file_full_path

#发送邮件
def fmail ( to_addr,hwymsg,file):
    current_date = datetime.date.today()
    # 发信方的信息:发信邮箱,QQ 邮箱授权码
    from_addr = '[email protected]'
    password = 'xxx'
    # 发信服务器
    smtp_server = 'smtp.exmail.qq.com'
    # 邮箱正文内容,第一个参数为内容,第二个参数为格式(plain 为纯文本),第三个参数为编码
    #构造消息对象
    msg = MIMEMultipart()
    #正文
    msgt = MIMEText(hwymsg, 'plain', 'utf-8')
    msg.attach(msgt)
    # 邮件头信息
    msg['From'] = Header('[email protected]')  # 发送者
    msg['To'] = Header(', '.join(to_addr))  # 接收者
    subject = str(current_date)+'--服务器巡检报告'
    msg['Subject'] = Header(subject, 'utf-8')  # 邮件主题

    # 添加附件
    annex = MIMEApplication(open(file, 'rb').read())  # 打开文件,读取文件
    annex["Content-Type"] = 'application/octet-stream'  # 设置内容类型
    annex.add_header('Content-Disposition', 'attachment', filename=str(current_date)+'巡检报告.html')  # 添加到header信息
    msg.attach(annex)
    try:
    #此处如果使用smtplib.SMTP_SSL 在windows上会卡住无反应、 linux无问题、 故使用smtplib.SMTP 
        smtpobj = smtplib.SMTP(smtp_server)
        #smtpobj = smtplib.SMTP(smtp_server,465) 此处465为端口、不指定时为默认端口465
        # 建立连接--邮箱服务和端口号(可百度查询)
        smtpobj.connect(smtp_server)
        # 登录--发送者账号和口令
        smtpobj.login(from_addr, password)
        # 发送邮件
        smtpobj.sendmail(from_addr, to_addr, msg.as_string())
        print("邮件发送成功")
    except smtplib.SMTPException:
        print("无法发送邮件")
    finally:
        # 关闭服务器
        smtpobj.quit()


# 获取要发送的附件名
fflie= get_latest_file('/zscript/serverpi/zserverpireport')

#邮件正文
hwym=''
hwym =hwym+'\n \n今日服务器巡检报告详情请见附件'


fmail(to_addr=['xxx@xxx','xxx@xxx'],hwymsg=hwym,file=fflie)


你可能感兴趣的:(Python,python)