Python发送多个附件和支持HTML及纯文本内容的 Email 实现

由于工作中经常需要收发电子邮件,例如每日(周)的工作报告,测试报告,监控告警,定时提醒等等,大都已电子邮件的形式发送。本文将实现一个 Python 的电子邮件发送类,支持发送多个附件(目录),HTML或纯文本内容,抄送收件人,多个接收者等功能。

代码实现

#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Copyright (C)  2015 By Thomas Hu.  All rights reserved.
@author : Thomas Hu
@version: 1.0
@created: 2015-05-17
'''
import base64
import httplib
import re
import os
import smtplib
from xml.etree import ElementTree
from email.utils import formatdate
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email.MIMEMultipart import MIMEMultipart
from email import Encoders

class EmailSender(object):
    def __init__(self, smtp_server, smtp_port=0, verbose=False, debug_level=1, encoding="utf-8"):
        ''' Initiate the EmailSender.
        @param smtp_server: the Email SMTP server.
        @param smtp_port:   the Email SMTP server port, if use the default port(25), you can set it to 0 or 25.
        @param verbose:     show the processing information if set to 'True', default is 'False'.
        @param debug_level: set the smtplib debug level, if it's '0', will enable debug information.
        @param encoding:    the encoding or charset for email body text or attachment file name, default is "utf-8".
        '''
        self.server = smtp_server
        self.port = int(smtp_port)
        self.verbose = verbose
        self.debug_level = int(debug_level)
        self.encoding = encoding
        self.attachments = []

        #Create smtp instance
        self.smtp = smtplib.SMTP(self.server, self.port)
        self.smtp.set_debuglevel(self.debug_level)
        self.print_verbose("Init SMTP server successfully. server=%s, port=%d."%(self.server, self.port))

    def print_verbose(self, message):
        '''Print the verbose information.
        @param message: the message to be print if the verbose is "True".
        '''
        if self.verbose:
            print(message)

    def login(self, user, password):
        '''Login to SMTP server.
        @param user:     the user name of the email sender.
        @param password: the passord of the user for login to SMTP server.
        '''
        self.from_addr = user + "@" + ".".join(self.server.split(".")[1:])
        try:
            self.print_verbose("Start to login into SMTP server.server=%s, port=%d."%(self.server, self.port))
            self.smtp.login(user, password)
            self.print_verbose("Login into SMTP server successfully.")
        except Exception as ex:
            print("Login into SMTP server failed! Error info: %s"%(str(ex)))

    def __add_attachment_file(self, filename, encoding, Filter):
        '''Add attachment file to the attachment list.
        @param filename:  the file name of attachment, should not be a path.
        @param encoding:  the encode of the attachment file name.
        @param Filter:    the file filter object, must implement 'accept(filename)' interface, and return True or False.
        '''
        # Check if the file is acceptable by the Filter
        if Filter is not None:
            try:
                accept = Filter.accept(filename)
            except:
                accept = False
            if accept == False:
                return
        # Add the attachment to the attachment list
        try:
            basename = os.path.basename(filename)
            attach = MIMEBase("application", "octet-stream")
            attach.set_payload(open(filename, "rb").read())
            #attach.add_header("Content-Disposition", "attachment;filename=%s"%(basename))
            attach.add_header("Content-Disposition", "attachment", filename=(encoding, "", basename))
            Encoders.encode_base64(attach)
            self.attachments.append(attach)
            self.print_verbose("Add attachment \"%s\" successfully."%(filename))
        except Exception as ex:
            print("Add attachment file \"%s\" failed. Error info: %s."%(filename, str(ex)))

    def add_attachment(self, path, encoding=None, Filter=None):
        '''Add attachment file to the attachment list.
        @param path:      the path of files to be added as attachment files. If is a directory, all of the files in it will be added.
        @param encoding:  the encode of the attachment file name.
        @param Filter:    the file filter object, must implement 'accept(filename)' interface, and return True or False.
        '''
        if not os.path.exists(path):
            self.print_verbose("Warning: attachment path \"%s\" is not exists."%(path))
            return
        charset = encoding if (encoding is not None) else self.encoding
        if os.path.isfile(path):
            return self.__add_attachment_file(path, charset, Filter)
        for root, dirs, files in os.walk(path):
            for f in files:
                fname = os.path.join(root, f)
                self.__add_attachment_file(fname, charset, Filter)

    def send_email(self, subject, to_addrs, cc_addrs, content, subtype="plain", charset=None):
        '''Send the email to the receivers.
        @param subject:    the email's subject(title).
        @param to_addrs:   the receivers' addresses, it's a list looks like ["[email protected]_server.com", "[email protected]_server.com"].
        @param cc_addrs:   the copy to receivers' addresses, has the same format as to_addrs.
        @param content:    the email message body, it can be plain text or HTML text, which depends on the parameter 'content_type'.
        @param subtype:    the content type, it can be "html" or "plain", default is "plain".
        @param charset:    the charset of message content, default is "None", use the same encoding as the initial function, which default is "utf-8".
        @return: if send successfully, return 'True', otherwise, return 'False'.
        '''
        charset = charset if charset is not None else self.encoding

        #Set the root information
        msg_root = MIMEMultipart("related")
        msg_root["Subject"] = subject
        msg_root["From"] = self.from_addr  # You can change it to any string
        msg_root["To"] = ",".join(to_addrs)
        msg_root["CC"] = ",".join(cc_addrs)
        msg_root["Date"] = formatdate(localtime=True)
        msg_root.preamble = "This is a multi-part message in MIME format."

        #Encapsulate the plain and HTML of the message body into an 'alternative' part,
        #so message agents can decide which they want to display.
        msg_alt = MIMEMultipart("alternative")

        #Set the message content
        msg_txt = MIMEText(content, subtype.lower(), charset)
        msg_alt.attach(msg_txt)

        #Add the alternative part to root part.
        msg_root.attach(msg_alt)

        #Add the attachment files
        for attach in self.attachments:
            msg_root.attach(attach)

        #Extend the copy to addresses to to_addrs
        to_addrs.extend(cc_addrs)

        #Send the email
        try:
            self.smtp.sendmail(self.from_addr, to_addrs, msg_root.as_string())
            self.print_verbose("Send email successfully.")
        except Exception as ex:
            print("Send email failed. Error info:%s"%(str(ex)))
            return False
        return True

    def close(self):
        '''Quit from the SMTP.
        '''
        self.smtp.quit()
        self.print_verbose("Logout SMTP server successfully.")

def test():
    smtp_server = "smtp.163.com"
    user = "yyy"
    password = "yyyxxx"
    from_addr = "[email protected]"
    to_addrs = ["[email protected]"]
    cc_addrs = []
    subject = "Email sending test"
    content ='Dear Friends,<p/><a href="http://blog.csdn.net/thomashtq"> Welcome to my CSDN blog!</a> <p/>Thanks a lot!'
    attach_files=[r"D:\temp\sendemail\attach"]

    emailsender = EmailSender(smtp_server, verbose=True)
    emailsender.login(user, password)
    for attach in attach_files:
        emailsender.add_attachment(attach, "utf-8")
    emailsender.send_email(subject, to_addrs, cc_addrs, content, subtype="html", charset="utf-8")
    emailsender.close()

if __name__ == '__main__':
    test()

代码中都有详细的解释,请原谅我用英文注释啊,习惯了^_^。 运行时,请将 test() 函数中相关的用户名、密码、服务器、收件人、附件列表等进行修改。也就是  test()函数中开头那段代码(空行之前的),根据自己的具体情况进行修改就 OK 了。

时间: 2024-10-31 17:23:42

Python发送多个附件和支持HTML及纯文本内容的 Email 实现的相关文章

[Python] 发送email的几种方式

python发送email还是比较简单的,可以通过登录邮件服务来发送,linux下也可以使用调用sendmail命令来发送,还可以使用本地或者是远程的smtp服务来发送邮件,不管是单个,群发,还是抄送都比较容易实现. 先把几个最简单的发送邮件方式记录下,像html邮件,附件等也是支持的,需要时查文档即可 1 登录邮件服务 #!/usr/bin/env python # -*- coding: utf-8 -*- #python2.7x #send_simple_email_by_account.

QQ超大附件最多支持2G,邮件附件20M到50M不等

QQ邮箱最大可发送50M普通附件(群邮件则限制在2M).此外也可以使用超大附件功能,支持将1G的文件发往任意邮箱.QQ邮箱根据你的QQ邮箱容量的不同制定相应的接受附件限制,包括附件在内,2G用户所发送和接收的邮件不能超出20M,3G用户不超过30M,4G用户不超过50M.接收的邮件如果超出了附件限制,会被退回到发件人.其实直接用QQ传文件最方便最简单. ---------------------------------------------------------------- 上传超大附件为

python发送电子邮件

或者收发邮件都得小心翼翼的,怕一不小心被有心人瞧见,又得被说说. 为了能发邮件而不被发现,嘿嘿.我就用python写了个邮件发送程序,用控制台控制,不了解的人一定以为哥还在编程工作呢.哈哈. 以下简介下怎样使用python发送邮件,包含普通文本内容,也能够带附件,或者HTML内容的邮件.能够说有了python,一切都变得很的easy. smtplib 模块是用来发送email的标准module,另外配合email.mime内的几个module实现起来就很的简单. [python] view pl

Python发送邮件(带附件)

import smtplib                           #发送邮件模块 from email.mime.text import MIMEText    #定义邮件内容 from email.mime.multipart import MIMEMultipart  #用于传送附件 #发送邮箱服务器 smtpserver='smtp.163.com' #发送邮箱用户名密码 user='[email protected]' password='*******' #发送和接收邮

ADManager Plus: 如何修改Exchange发送的邮件附件大小

ADManager Plus: 如何修改Exchange发送的邮件附件大小项目工期紧!时间宝贵!今天就要提交和完成报告审核!然而,项目的负责人试着发送邮件却受到邮件发送失败的消息,只是因为附件太大.不仅仅像这位负责人这样,项目组的其他成员也需要发送比这位负责人发送的附件更大的文件.因此,只好向IT发出紧急求救电话.如果您是IT管理员将会做些什么呢?这个项目50个人参与,现在也没有时间去考虑一个脚本或者下载一个免费软件来帮您完成这项任务.另外,您更没有时间手动更改50个用户的邮件附件大小.使用AD

基于javaMail的邮件发送--excel作为附件

基于JavaMail的Java邮件发送 Author [email protected] Desc 简单邮件发送 Date 2017/12/8 项目中需要根据物料资质的状况实时给用户发送邮件,然后我就简单学习了SMTP. 电子邮件的在网络中传输和网页一样需要遵从特定的协议,常用的电子邮件协议包括 SMTP,POP3,IMAP.其中邮件的创建和发送只需要用到 SMTP协议,所以本文也只会涉及到SMTP协议.SMTP 是 Simple Mail Transfer Protocol 的简称,即简单邮件

python发送微信

申请企业微信 使用python发送信息到企业微信,同时支持python2与python3环境,需要先申请一个企业微信,然后创建应用,获取以下三个信息 企业IP.Agentid.Secret 网信为创建的应用名称 脚本描述 将以上三个信息替换到脚本中,主要是 class WeiXin(object):部分,其他的辅助性工具类,收集的一些常用脚本可不用关注 #!/usr/bin/env python #coding=utf-8 ''' Created on 2018年2月8日 @author: ro

使用Python发送、订阅消息

使用Python发送.订阅消息 使用插件 paho-mqtt 官方文档:http://shaocheng.li/post/blog/2017-05-23 Paho 是一个开源的 MQTT 客户端项目,提供多种语言的 MQTT 客户端实现,包括 C.C++.C#.Java.Python.JavaScript 等,完全支持 MQTT v3.1 和 v3.1.1 .Paho Python Client 是它的 Python 语言版本,支持 Python 2.7 和 3.x .更多特性可以查看 http

python发送网易邮件

无附件 from smtplib import SMTP from email.header import Header from email.mime.text import MIMEText def main(): sender = '1355***[email protected]' receivers = '1047**[email protected]' message = MIMEText('用python发送邮件的实例代码','plain','utf-8') message['Su