Python发送邮件

Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。
Python对SMTP支持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件。
  • 发送纯文本内容:
# 引入相应的模块
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.multipart import MIMEBase
from email import encoders
from email.utils import parseaddr, formataddr

class SendMail(object):
   def __init__(self):
       self.fromUser = "xxxxxx@qq.com" 
       self.userPasswd = "xxxxxx"      # 此处是qq邮箱授权码, 不是登录密码
       self.smtpAddr = "smtp.qq.com"

   # 构造邮件结构
   # toAddrs 收件人可以是多个,["xxx@qq.com","xxx@qq.com"], subject 邮件的主题, msg 邮件的内容
   def mailStructure(self, toAddrs, subject, msg):
       # 邮件对象:
       mailMsg = MIMEMultipart()
       mailMsg['Subject'] = ("Hello <%s>" % subject)
       mailMsg['From'] = ("Python管理员 <%s>" % self.fromUser)
       mailMsg['To'] = ','.join(toAddrs)
       # 邮件正文是MIMEText :
       mailMsg.attach(MIMEText(msg, 'html', 'utf-8'))
       return mailMsg.as_string()

   # 发送邮件
   def sendMail(self, toAddrs, subject, msg):
       mailMsg_as_string = self.mailStructure(toAddrs, subject, msg)
       # 连接服务器发送邮件
       try:
           server = smtplib.SMTP_SSL(self.smtpAddr, 465)
           server.connect(self.smtpAddr)  # 连接smtp服务器
           server.login(self.fromUser, self.userPasswd)  # 登录邮箱
           server.sendmail(self.fromUser, toAddrs, mailMsg_as_string)  # 发送邮件
           server.quit()
       except Exception:
           print("Error: unable to send email")


a = SendMail()
a.sendMail(["381347268@qq.com", "44934875@qq.com"], "测试主题", "测试内容")

  • 效果图


    发送纯文本内容效果图
如果Email中要加上附件怎么办?带附件的邮件可以看做包含若干部分的邮件:文本和各个附件本身,所以,可以构造一个MIMEMultipart对象代表邮件本身,然后往里面加上一个MIMEText作为邮件正文,再继续往里面加上表示附件的MIMEBase对象即可:

其实就是打开图片并引入(加上这段内容)

with open(r"C:\Users\YJ\Desktop\favicon.png", "rb") as f:
            # 设置附件的MIME和文件名,这里是png类型:
            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.set_payload(f.read())
            # 用Base64编码:
            encoders.encode_base64(mime)
            # 添加到MIMEMultipart:
            mailMsg.attach(mime)
  • 发送附件图片 (完整代码如下:)
# 引入相应的模块
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.multipart import MIMEBase
from email import encoders
from email.utils import parseaddr, formataddr

class SendMail(object):
    def __init__(self):
        self.fromUser = "xxxxxx@qq.com" 
        self.userPasswd = "xxxxxx"      # 此处是qq邮箱授权码, 不是登录密码
        self.smtpAddr = "smtp.qq.com"

    # 构造邮件结构
    # toAddrs 收件人可以是多个,["xxx@qq.com","xxx@qq.com"], subject 邮件的主题, msg 邮件的内容
    def mailStructure(self, toAddrs, subject, msg):
        # 邮件对象:
        mailMsg = MIMEMultipart()
        mailMsg['Subject'] = ("Hello <%s>" % subject)
        mailMsg['From'] = ("Python管理员 <%s>" % self.fromUser)
        mailMsg['To'] = ','.join(toAddrs)
        # 邮件正文是MIMEText :
        mailMsg.attach(MIMEText(msg, 'html', 'utf-8'))

        # 发送图片附件, 需要用到附件对象MIMEBase对象, 需要引入from email.mime.multipart import MIMEBase
        # 添加附件就是加上一个MIMEBase,从本地读取一个图片:
        with open(r"C:\Users\YJ\Desktop\favicon.png", "rb") as f:
            # 设置附件的MIME和文件名,这里是png类型:
            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.set_payload(f.read())
            # 用Base64编码:
            encoders.encode_base64(mime)
            # 添加到MIMEMultipart:
            mailMsg.attach(mime)
        return mailMsg.as_string()
    # 发送邮件
    def sendMail(self, toAddrs, subject, msg):
        mailMsg_as_string = self.mailStructure(toAddrs, subject, msg)
        # 连接服务器发送邮件
        try:
            server = smtplib.SMTP_SSL(self.smtpAddr, 465)
            server.connect(self.smtpAddr)  # 连接smtp服务器
            server.login(self.fromUser, self.userPasswd)  # 登录邮箱
            server.sendmail(self.fromUser, toAddrs, mailMsg_as_string)  # 发送邮件
            server.quit()
        except Exception:
            print("Error: unable to send email")

a = SendMail()
a.sendMail(["381347268@qq.com", "44934875@qq.com"], "测试主题", "测试内容")

  • 效果图


    附件图片效果图
如果要把一个图片嵌入到邮件正文中怎么做?直接在HTML邮件中链接图片地址行不行?答案是,大部分邮件服务商都会自动屏蔽带有外链的图片,因为不知道这些链接是否指向恶意网站。
要把图片嵌入到邮件正文中,我们只需按照发送附件的方式,先把邮件作为附件添加进去,然后,在HTML中通过引用src="cid:0"就可以把附件作为图片嵌入了。如果有多个图片,给它们依次编号,然后引用不同的cid:x即可。

其实就是将MIMEText 格式改变一下

mailMsg.attach(MIMEText('<html><body><h1>%s</h1>' % (msg) + '<p><img src="cid:0"></p>' + '</body></html>', 'html','utf-8'))
  • 将附件图片包含在邮件内容中(完整代码如下:)
# 引入相应的模块
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.multipart import MIMEBase
from email import encoders
from email.utils import parseaddr, formataddr

class SendMail(object):
    def __init__(self):
        self.fromUser = "xxxxxx@qq.com" 
        self.userPasswd = "xxxxxx"      # 此处是qq邮箱授权码, 不是登录密码
        self.smtpAddr = "smtp.qq.com"

    # 构造邮件结构
    # toAddrs 收件人可以是多个,["xxx@qq.com","xxx@qq.com"], subject 邮件的主题, msg 邮件的内容
    def mailStructure(self, toAddrs, subject, msg):
        # 邮件对象:
        mailMsg = MIMEMultipart()
        mailMsg['Subject'] = ("Hello <%s>" % subject)
        mailMsg['From'] = ("Python管理员 <%s>" % self.fromUser)
        mailMsg['To'] = ','.join(toAddrs)
        # 邮件正文是MIMEText :
        # 加载图片并引入到邮件内容中来
        mailMsg.attach(MIMEText('<html><body><h1>%s</h1>' % (msg) + '<p><img src="cid:0"></p>' + '</body></html>', 'html','utf-8'))
        # 发送图片附件, 需要用到附件对象MIMEBase对象, 需要引入from email.mime.multipart import MIMEBase
        # 添加附件就是加上一个MIMEBase,从本地读取一个图片:
        with open(r"C:\Users\YJ\Desktop\favicon.png", "rb") as f:
            # 设置附件的MIME和文件名,这里是png类型:
            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.set_payload(f.read())
            # 用Base64编码:
            encoders.encode_base64(mime)
            # 添加到MIMEMultipart:
            mailMsg.attach(mime)
        return mailMsg.as_string()

    # 发送邮件
    def sendMail(self, toAddrs, subject, msg):
        mailMsg_as_string = self.mailStructure(toAddrs, subject, msg)
        # 连接服务器发送邮件
        try:
            server = smtplib.SMTP_SSL(self.smtpAddr, 465)
            server.connect(self.smtpAddr)  # 连接smtp服务器
            server.login(self.fromUser, self.userPasswd)  # 登录邮箱
            server.sendmail(self.fromUser, toAddrs, mailMsg_as_string)  # 发送邮件
            server.quit()
        except Exception:
            print("Error: unable to send email")

a = SendMail()
a.sendMail(["381347268@qq.com", "44934875@qq.com"], "测试主题", "测试内容")

  • 效果图


    邮件内容包含附件图片
  • 发送纯文本附件
# 引入相应的模块
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.multipart import MIMEBase
from email import encoders
from email.utils import parseaddr, formataddr

class SendMail(object):
    def __init__(self):
        self.fromUser = "xxxxxx@qq.com" 
        self.userPasswd = "xxxxxx"      # 此处是qq邮箱授权码, 不是登录密码
        self.smtpAddr = "smtp.qq.com"


    # 构造邮件结构
    # toAddrs 收件人可以是多个,["xxx@qq.com","xxx@qq.com"], subject 邮件的主题, msg 邮件的内容
    def mailStructure(self, toAddrs, subject, msg):
        # 邮件对象:
        mailMsg = MIMEMultipart()
        mailMsg['Subject'] = ("Hello <%s>" % subject)
        mailMsg['From'] = ("Python管理员 <%s>" % self.fromUser)
        mailMsg['To'] = ','.join(toAddrs)
        # 邮件正文是MIMEText :
        mailMsg.attach(MIMEText(msg, 'html', 'utf-8'))


        # 发送文件附件, 需要用到附件对象MIMEBase对象, 需要引入from email.mime.multipart import MIMEBase
        # 添加附件就是加上一个MIMEBase,从本地读取一个文件:
        with open(r"C:\Users\YJ\Desktop\aaa.txt", "rb") as f:
            # 设置附件的MIME和文件名,这里是png类型:
            mime = MIMEBase("txta", "txt", filename="test.txt")
            # 加上必要的头信息:
            mime.add_header('Content-Disposition', 'attachment', filename='test.txt')
            mime.add_header('Content-ID', '<0>')
            mime.add_header('X-Attachment-Id', '0')
            # 把附件的内容读进来:
            mime.set_payload(f.read())
            # 用Base64编码:
            encoders.encode_base64(mime)
            # 添加到MIMEMultipart:
            mailMsg.attach(mime)
        return mailMsg.as_string()
    # 发送邮件
    def sendMail(self, toAddrs, subject, msg):
        mailMsg_as_string = self.mailStructure(toAddrs, subject, msg)
        # 连接服务器发送邮件
        try:
            server = smtplib.SMTP_SSL(self.smtpAddr, 465)
            server.connect(self.smtpAddr)  # 连接smtp服务器
            server.login(self.fromUser, self.userPasswd)  # 登录邮箱
            server.sendmail(self.fromUser, toAddrs, mailMsg_as_string)  # 发送邮件
            server.quit()
        except Exception:
            print("Error: unable to send email")

a = SendMail()
a.sendMail(["381347268@qq.com", "44934875@qq.com"], "测试主题", "测试内容")

  • 效果图


    纯文本附件效果图
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容

  • python发送邮件 准备 python中发送邮件主要用的是smtplib和email两个模块,下面主要对这两个模...
    爱撒谎的男孩阅读 493评论 0 2
  • 背景 公司内网有个论坛,各种公司的前沿消息都会有人在讨论。一忙起来,经常忘记逛论坛,所以写了个爬虫,爬取论坛前10...
    aialin阅读 927评论 0 11
  • 简单邮件传输协议(SMTP)是一种协议,用于在邮件服务器之间发送电子邮件和路由电子邮件。 Python提供smtp...
    易百教程阅读 43,787评论 4 62
  • 【姓名】刘芳 【派别】文魁派 【导师】袁文魁 【分舵】第二分舵 【舵主】罗婷予 拖欠作业,心理会觉得有压力,并且有...
    溜冰的方块阅读 948评论 3 0
  • 今天早间新闻预报有雨,结果走出办公楼的西门,金灿灿的西落之光普照大地,久坐室内空调下的我顿觉得股股热流环绕全身,这...
    杰瑞的Jerry阅读 353评论 0 0