Python发送邮件各种姿势

本章目录Python标准库smtplib

Python发送邮件并抄送

Python发送邮件带附件

Python发送HTML邮件

Python发送图片邮件

在写脚本时,放到后台运行,想知道执行情况,会通过邮件、SMS(短信)、飞信、微信等方式通知管理员,用的最多的是邮件。在linux下,Shell脚本发送邮件告警是件很简单的事,有现成的邮件服

在写脚本时,放到后台运行,想知道执行情况,会通过邮件、SMS(短信)、飞信、微信等方式通知管理员,用的最多的是邮件。在linux下,Shell脚本发送邮件告警是件很简单的事,有现成的邮件服务软件或者调用运营商邮箱服务器。

对于Python来说,需要编写脚本调用邮件服务器来发送邮件,使用的协议是SMTP。接收邮件,使用的协议是POP3和IMAP。我想有必要说明下 ,POP3和IMAP的区别:POP3在客户端邮箱中所做的操作不会反馈到邮箱服务器,比如删除一封邮件,邮箱服务器并不会删除。IMAP则会反馈到邮箱服务器,会做相应的操作。

1、Python标准库smtplib

Python分别提供了收发邮件的库:smtplib、poplib和imaplib。

其中smtplib库是用于发送邮件的,smtplib库主要用smtplib.SMTP()类,它用于连接SMTP服务器和发送邮件。

这个类有几个常用的方法:方法描述

SMTP.set_debuglevel(level)设置输出debug调试信息,默认不输出

SMTP.docmd(cmd[, argstring])发送一个命令到SMTP服务器

SMTP.connect([host[, port]])连接到指定的SMTP服务器

SMTP.helo([hostname])使用helo指令向SMTP服务器确认你的身份

SMTP.ehlo(hostname)使用ehlo指令像ESMTP(SMTP扩展)确认你的身份

SMTP.ehlo_or_helo_if_needed()如果在以前的会话连接中没有提供ehlo或者helo指令,这个方法会调用ehlo()或helo()

SMTP.has_extn(name)判断指定名称是否在SMTP服务器上

SMTP.verify(address)判断邮件地址是否在SMTP服务器上

SMTP.starttls([keyfile[, certfile]])使SMTP连接运行在TLS模式,所有的SMTP指令都会被加密

SMTP.login(user, password)登录SMTP服务器

SMTP.sendmail(from_addr, to_addrs, msg,  mail_options=[], rcpt_options=[])发送邮件

from_addr:邮件发件人

to_addrs:邮件收件人

msg:发送消息

SMTP.quit()关闭SMTP会话

SMTP.close()关闭SMTP服务器连接

看下官方给的示例:>>> import smtplib

>>> s=smtplib.SMTP("localhost")

>>> tolist=["one@one.org","two@two.org","three@three.org","four@four.org"]

>>> msg = '''\

... From: Me@my.org

... Subject: testin'...

...

... This is a test '''

>>> s.sendmail("me@my.org",tolist,msg)

{ "three@three.org" : ( 550 ,"User unknown" ) }

>>> s.quit()

我们根据示例给自己发一个邮件测试下:

我这里测试使用本地的SMTP服务器,也就是要装一个支持SMTP协议的服务,比如sendmail、postfix等。

CentOS安装sendmail:yum install sendmail>>> import smtplib

>>> s = smtplib.SMTP("localhost")

>>> tolist = ["xxx@qq.com", "xxx@163.com"]

>>> msg = '''\

... From: Me@my.org

... Subject: test

... This is a test '''

>>> s.sendmail("me@my.org", tolist, msg)

{}

进入腾讯和网易收件人邮箱,就能看到刚发的测试邮件,一般都被邮箱服务器过滤成垃圾邮件,所以收件箱没有,你要去垃圾箱看看。

可以看到,多个收件人可以放到一个列表中进行群发。msg对象里From表示发件人,Subject是邮件标题,换行后输入的是邮件内容。

上面是使用本地SMTP服务器发送的邮件,测试下用163服务器发送邮件看看效果:>>> import smtplib

>>> s = smtplib.SMTP("smtp.163.com")

>>> s.login("baojingtongzhi@163.com", "xxx")

(235, 'Authentication successful')

>>> tolist = ["xxx@qq.com", "xxx@163.com"]

>>> msg = '''\

... From: baojingtongzhi@163.com

... Subject: test

... This is a test '''

>>> s.sendmail("baojingtongzhi@163.com", tolist, msg)

Traceback (most recent call last):

File "", line 1, in

File "/usr/lib64/python2.6/smtplib.py", line 725, in sendmail

raise SMTPDataError(code, resp)

smtplib.SMTPDataError: (554, 'DT:SPM 163 smtp10,DsCowAAXIdDIJAtYkZiTAA--.65425S2 1477125592,please see http://mail.163.com/help/help_spam_16.htm?ip=119.57.73.67&hostid=smtp10&time=1477125592')

访问给出的163网址,SMTP554错误是:”554 DT:SUM 信封发件人和信头发件人不匹配;”

大概已经明白啥意思,看上面再使用本地SMTP服务器时候,收件人位置是“undisclosed-recipients”,看这样163的SMTP服务器不给我们服务的原因就是这里收件人没指定。

重新修改下msg对象,添加上收件人:>>> msg = '''\

... From: baojingtongzhi@163.com

... To: 962510244@qq.com ,xxx@163.com

... Subject: test

...

... This is a test '''

>>> s.sendmail("baojingtongzhi@163.com", tolist, msg)

{}

好了,可以正常发送邮件了。msg这个格式是SMTP规定的,一定要遵守。

2、Python发送邮件并抄送#!/usr/bin/python

# -*- coding: utf-8 -*-

import smtplib

def sendMail(body):

smtp_server = 'smtp.163.com'

from_mail = 'baojingtongzhi@163.com'

mail_pass = 'xxx'

to_mail = ['xxx@qq.com', 'xxx@163.com']

cc_mail = ['lizhenliang@xxx.com']

from_name = 'monitor'

subject = u'监控'.encode('gbk')   # 以gbk编码发送,一般邮件客户端都能识别

#     msg = '''\

# From: %s

# To: %s

# Subject: %s

# %s''' %(from_name, from_mail, to_mail_str, subject, body)  # 这种方式必须将邮件头信息靠左,也就是每行开头不能用空格,否则报SMTP 554

mail = [

"From: %s " % (from_name, from_mail),

"To: %s" % ','.join(to_mail),   # 转成字符串,以逗号分隔元素

"Subject: %s" % subject,

"Cc: %s" % ','.join(cc_mail),

"",

body

]

msg = '\n'.join(mail)  # 这种方式先将头信息放到列表中,然后用join拼接,并以换行符分隔元素,结果就是和上面注释一样了

try:

s = smtplib.SMTP()

s.connect(smtp_server, '25')

s.login(from_mail, mail_pass)

s.sendmail(from_mail, to_mail+cc_mail, msg)

s.quit()

except smtplib.SMTPException as e:

print "Error: %s" %e

if __name__ == "__main__":

sendMail("This is a test!")

s.sendmail(from_mail,to_mail+cc_mail, msg) 在这里注意下,收件人和抄送人为什么放一起发送呢?其实无论是收件人还是抄送人,它们收到的邮件都是一样的,SMTP都是认为收件人这样一封一封的发出。所以实际上并没有抄送这个概念,只是在邮件头加了抄送人的信息罢了!另外,如果不需要抄送人,直接把上面cc的信息去掉即可。

3、Python发送邮件带附件

由于SMTP.sendmail()方法不支持添加附件,所以可以使用email模块来满足需求。email模块是一个构造邮件和解析邮件的模块。

先看下如何用email库构造一个简单的邮件:message = Message()

message['Subject'] = '邮件主题'

message['From'] = from_mail

message['To'] = to_mail

message['Cc'] = cc_mail

message.set_payload('邮件内容')

基本的格式就是这样的!

继续回到主题,发送邮件带附件:#!/usr/bin/python

# -*- coding: utf-8 -*-

import smtplib

from email.mime.text import MIMEText

from email.mime.multipart import MIMEMultipart

from email.header import Header

from email import encoders

from email.mime.base import MIMEBase

from email.utils import parseaddr, formataddr

# 格式化邮件地址

def formatAddr(s):

name, addr = parseaddr(s)

return formataddr((Header(name, 'utf-8').encode(), addr))

def sendMail(body, attachment):

smtp_server = 'smtp.163.com'

from_mail = 'baojingtongzhi@163.com'

mail_pass = 'xxx'

to_mail = ['xxx@qq.com', 'xxx@163.com']

# 构造一个MIMEMultipart对象代表邮件本身

msg = MIMEMultipart()

# Header对中文进行转码

msg['From'] = formatAddr('管理员 ' % from_mail).encode()

msg['To'] = ','.join(to_mail)

msg['Subject'] = Header('监控', 'utf-8').encode()

# plain代表纯文本

msg.attach(MIMEText(body, 'plain', 'utf-8'))

# 二进制方式模式文件

with open(attachment, 'rb') as f:

# MIMEBase表示附件的对象

mime = MIMEBase('text', 'txt', filename=attachment)

# filename是显示附件名字

mime.add_header('Content-Disposition', 'attachment', filename=attachment)

# 获取附件内容

mime.set_payload(f.read())

encoders.encode_base64(mime)

# 作为附件添加到邮件

msg.attach(mime)

try:

s = smtplib.SMTP()

s.connect(smtp_server, "25")

s.login(from_mail, mail_pass)

s.sendmail(from_mail, to_mail, msg.as_string())  # as_string()把MIMEText对象变成str

s.quit()

except smtplib.SMTPException as e:

print "Error: %s" % e

if __name__ == "__main__":

sendMail('附件是测试数据, 请查收!', 'test.txt')

4、Python发送HTML邮件#!/usr/bin/python

# -*- coding: utf-8 -*-

import smtplib

from email.mime.text import MIMEText

from email.mime.multipart import MIMEMultipart

from email.header import Header

from email.utils import parseaddr, formataddr

# 格式化邮件地址

def formatAddr(s):

name, addr = parseaddr(s)

return formataddr((Header(name, 'utf-8').encode(), addr))

def sendMail(body):

smtp_server = 'smtp.163.com'

from_mail = 'baojingtongzhi@163.com'

mail_pass = 'xxx'

to_mail = ['xxx@qq.com', 'xxx@163.com']

# 构造一个MIMEMultipart对象代表邮件本身

msg = MIMEMultipart()

# Header对中文进行转码

msg['From'] = formatAddr('管理员 ' % from_mail).encode()

msg['To'] = ','.join(to_mail)

msg['Subject'] = Header('监控', 'utf-8').encode()

msg.attach(MIMEText(body, 'html', 'utf-8'))

try:

s = smtplib.SMTP()

s.connect(smtp_server, "25")

s.login(from_mail, mail_pass)

s.sendmail(from_mail, to_mail, msg.as_string())  # as_string()把MIMEText对象变成str

s.quit()

except smtplib.SMTPException as e:

print "Error: %s" % e

if __name__ == "__main__":

body = """

测试邮件

This is a test

"""

sendMail(body)

5、Python发送图片邮件#!/usr/bin/python

# -*- coding: utf-8 -*-

import smtplib

from email.mime.text import MIMEText

from email.mime.image import MIMEImage

from email.mime.multipart import MIMEMultipart

from email.header import Header

from email.utils import parseaddr, formataddr

# 格式化邮件地址

def formatAddr(s):

name, addr = parseaddr(s)

return formataddr((Header(name, 'utf-8').encode(), addr))

def sendMail(body, image):

smtp_server = 'smtp.163.com'

from_mail = 'baojingtongzhi@163.com'

mail_pass = 'xxx'

to_mail = ['xxx@qq.com', 'xxx@163.com']

# 构造一个MIMEMultipart对象代表邮件本身

msg = MIMEMultipart()

# Header对中文进行转码

msg['From'] = formatAddr('管理员 ' % from_mail).encode()

msg['To'] = ','.join(to_mail)

msg['Subject'] = Header('监控', 'utf-8').encode()

msg.attach(MIMEText(body, 'html', 'utf-8'))

# 二进制模式读取图片

with open(image, 'rb') as f:

msgImage = MIMEImage(f.read())

# 定义图片ID

msgImage.add_header('Content-ID', '')

msg.attach(msgImage)

try:

s = smtplib.SMTP()

s.connect(smtp_server, "25")

s.login(from_mail, mail_pass)

s.sendmail(from_mail, to_mail, msg.as_string())  # as_string()把MIMEText对象变成str

s.quit()

except smtplib.SMTPException as e:

print "Error: %s" % e

if __name__ == "__main__":

body = """

测试图片

# 引用图片

"""

sendMail(body, 'test.png')

以上是Python常见的发送邮件方式,经常写脚本的朋友还是有必要熟悉下的!

php sendmail 抄送,Python发送邮件各种姿势相关推荐

  1. 为什么每个邮件收到后都会有一个htm的附件_Python 发送邮件各种姿势

    电子邮件是互联网应用最广的通讯服务,在工作中经常会有自动发邮件的需求,例如监控告警.注册通知.激活链接等. 而发送邮件是基于SMTP协议,接收邮件则是基于POP3或IMAP协议. 那POP3与IMAP ...

  2. python接口自动化(三十二)--Python发送邮件(常见四种邮件内容)番外篇——上(详解)...

    简介 本篇文章与前边没有多大关联,就是对前边有关发邮件的总结和梳理.在写脚本时,放到后台运行,想知道执行情况,会通过邮件.SMS(短信).飞信.微信等方式通知管理员,用的最多的是邮件.在linux下, ...

  3. python接口自动化(三十二)--Python发送邮件(常见四种邮件内容)番外篇——上

    简介 本篇文章与前边没有多大关联,就是对前边有关发邮件的总结和梳理.在写脚本时,放到后台运行,想知道执行情况,会通过邮件.SMS(短信).飞信.微信等方式通知管理员,用的最多的是邮件.在linux下, ...

  4. Python发送邮件及踩坑总结

    Python发送邮件踩坑总结 ​ 因项目需要,要用公司邮箱向qq邮箱发送大概3000封邮件,发送过程中踩了不少坑,特地发出来分享一下 话不多说,先贴出来邮件发送代码,后面再讲坑.主要是针对于腾讯邮箱的 ...

  5. 利用python发送邮件

    利用python发送邮件 使用outlook 使用Smtp 本文主要介绍python发送邮件的两种方式 使用outlook 该方式需要安装对应的包 命令如下 pip install pypiwin32 ...

  6. python邮件发送哪个好_最全总结!聊聊 Python 发送邮件的几种方式

    1. 前言 邮件,作为最正式规范的沟通方式,在日常办公过程中经常被用到 我们都知道 Python内置了对 SMTP 的支持,可以发送纯文本.富文本.HTML 等格式的邮件 本文将聊聊利用 Python ...

  7. 用Python发送邮件[zt]

    用Python发送邮件 服务器需要周期性的检查邮件队列,然后通过smtp服务器发送出去,就网上搜了搜,然后修改了加工了一下,写了一个邮件发送的简单模块 两个文件 config.py:配置信息 send ...

  8. python发送邮件及附件

    今天给大伙说说python发送邮件,官方的多余的话自己去百度好了,还有一大堆文档说实话不到万不得已的时候一般人都不会去看,回归主题: 本人是mac如果没有按照依赖模块的请按照下面的截图安装 导入模块如 ...

  9. python 发送邮件connect none_Python发送邮件功能示例【使用QQ邮箱】

    本文实例讲述了Python发送邮件功能.分享给大家供大家参考,具体如下: 这里以QQ邮箱为例说明 登录邮箱点账号 开启smtp 开启时会要求你发送一条短信,发送完成后点已发送. 就有授权码了 代码如下 ...

  10. python 发送邮件的两种方式【终极篇】

    python 发送邮件的两种方式[终极篇] 一,利用python自带的库 smtplib简单高效 from email.mime.multipart import MIMEMultipart from ...

最新文章

  1. 『图解Java并发』面试必问的CAS原理你会了吗?
  2. 給曾經的三年,寫點什么吧。-紀念華軟
  3. SAP 系统参数设置 RZ10 RZ11
  4. java jar log4j_使用Log4j
  5. Spark Streaming(二)Flume
  6. C++ getline() 和 get()
  7. r语言中1c0怎么表示什么,r语言表示或者用什么符号?
  8. C++ 基本数据类型 的 字节数
  9. 计算机操作系统学习笔记_6_进程管理 --死锁
  10. 抖音内测语音直播功能 支持8位观众同时在线聊天
  11. 1.7 理解 Dropout
  12. 风控模型及特征的上线部署方法
  13. python的ctypes模块详解数组_如何使用Python的ctypes和readinto读取包含数组的结构?...
  14. .net实现调用本地exe等应用程序的办法总结
  15. java程序往微信群里发消息_通过java程序,给微信发送消息
  16. 【I.MX6ULL】6ull 加载 linux 驱动模块失败
  17. [算法学习no5]kmp
  18. 尺寸公差分析尺寸链计算软件:新能源电池行业—模组散热系统之弹簧长度计算
  19. 计世资讯:用户对大数据安全分析需求逐渐迫切
  20. java币值转换_币值转换

热门文章

  1. 【Python】完美采集淘宝数据(附完整源代码和视频教程)
  2. 副高相当于副处吗_事单副高职称相当于副处待遇?别逗了,连公务员副科实职都不如...
  3. antd 表单通过form.getFieldsValue获取不全tabs组件下表单数据的问题
  4. C++课程设计:学生管理系统
  5. 分享:MSDN visual studio 2010简体中文旗舰版,专业版下载(内置正版密钥)
  6. 心形炫彩LED灯设计
  7. 网络与社会导论之幂律与富者更富及其与长尾、齐普夫定律等的关系
  8. 首行缩进字符计算机怎么弄,首行缩进2字符如何设置
  9. 用于将 InfoPath 2007 集成到 Visual Studio 2005 中的 InfoPath Designer API 概述
  10. 修改hexo的主题nexT中的Pisces主题宽度