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

简介

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

件服务软件或者调用运营商邮箱服务器。

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

会删除。IMAP则会反馈到邮箱服务器,会做相应的操作。

  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服务器连接

看下官方给的示例:

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

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

CentOS安装sendmail:yum install sendmail

1>>> import smtplib2>>> s = smtplib.SMTP("localhost")3>>> tolist = ["xxx@qq.com","xxx@163.com"]4>>> msg ='''\5... From: Me@my.org6... Subject: test7... Thisisa test'''8>>> s.sendmail("me@my.org", tolist, msg)9{}

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

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

1.1 Python发送邮件并抄送

1#!/usr/bin/python 2# -*- coding: utf-8-*- 3import smtplib 4def sendMail(body): 5smtp_server ='smtp.163.com' 6from_mail ='hongge@163.com' 7mail_pass ='xxx' 8to_mail = ['xxx@qq.com','xxx@163.com'] 9cc_mail = ['hongge@xxx.com']10from_name ='monitor'11subject = u'监控'.encode('gbk')  # 以gbk编码发送,一般邮件客户端都能识别12#    msg ='''\13# From: %s <%s>14# To: %s15# Subject: %s16# %s''' %(from_name, from_mail, to_mail_str, subject, body)  # 这种方式必须将邮件头信息靠左,也就是每行开头不能用空格,否则报SMTP 55417mail = [18"From: %s <%s>"% (from_name, from_mail),19"To: %s"%','.join(to_mail),  # 转成字符串,以逗号分隔元素20"Subject: %s"% subject,21"Cc: %s"%','.join(cc_mail),22"",23        body24        ]25msg ='\n'.join(mail)  # 这种方式先将头信息放到列表中,然后用join拼接,并以换行符分隔元素,结果就是和上面注释一样了26try:27s = smtplib.SMTP()28s.connect(smtp_server,'25')29        s.login(from_mail, mail_pass)30s.sendmail(from_mail, to_mail+cc_mail, msg)  31        s.quit()32except smtplib.SMTPExceptionas e:33print"Error: %s"%e34if__name__ =="__main__":35sendMail("This is a test!")

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

另外以上代码发送的邮件会出现主题中文乱码:

解决方案:三行代码即可,修改成红色框代码即可

1.2 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('邮件内容')

基本的格式就是这样的!

继续回到主题,发送邮件带附件:

1# coding=utf-8 2#1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 3 4#2.注释:包括记录创建时间,创建人,项目名称。 5''' 6Created on2019-5-9 7@author: 北京-宏哥 8Project:学习和使用邮箱发带有附件邮件 9'''10#3.导入模块11import smtplib12from email.mime.text import MIMEText13from email.mime.multipart import MIMEMultipart14from email.header import Header15from email import encoders16fromemail.mime.base import MIMEBase1718def send_mail(file_new):19#-----------1.跟发件相关的参数------20smtpserver ='smtp.mxhichina.com'                #发件服务器21port =0                      #端口22username ='noreply@cxx.cn'  #发件箱用户名23password ='xx@@123'        #发件箱密码24sender ='noreply@cxx.cn'    #发件人邮箱25receiver = ['hongge@cedex.cn','1918991791@qq.com'] #收件人邮箱26# ----------2.编辑邮件的内容------27    #读文件内容28f = open(file_new,'rb')29mail_body = f.read()30    f.close()31    # 邮件正文是MIMEText32body = MIMEText(mail_body,'html','utf-8')33    # 邮件对象34msg = MIMEMultipart()35msg['Subject'] = Header("自动化测试报告",'utf-8').encode()#主题36msg['From'] = Header(u'测试机 <%s>'%sender)                #发件人37msg['To'] = Header(u'测试负责人 <%s>'%receiver)            #收件人38msg['To'] =';'.join(receiver)39    msg.attach(body)40    # # MIMEBase表示附件的对象41att = MIMEText(mail_body,"base64","utf-8")42att["Content-Type"] ="application/octet-stream"43    # filename是显示附件名字44att["Content-Disposition"] ='attachment; filename="test_report.html"'45    msg.attach(att)46# ----------3.发送邮件------47try:48smtp = smtplib.SMTP()49        smtp.connect(smtpserver)  # 连服务器50        smtp.login(sender, password)51    except:52smtp = smtplib.SMTP_SSL(smtpserver, port)53        smtp.login(sender, password)  # 登录54    smtp.sendmail(sender, receiver, msg.as_string())  # 发送55    smtp.quit()5657if__name__ =="__main__":58    #本地文件的路径59att_path= r'E:\pythontest\text.txt'60send_mail(att_path)


1.3 Python发送HTML邮件

1# coding=utf-8 2#1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 3 4#2.注释:包括记录创建时间,创建人,项目名称。 5''' 6Created on2019-5-9 7@author: 北京-宏哥 8Project:学习和使用邮箱发HTML邮件 9'''10#3.导入模块11#"-*- coding: utf-8 -*-"12import smtplib13from email.mime.text import MIMEText1415mail_user="XXX@163.com"16mail_password="******q1125"17mailto_list=["1918991791<1918991791@qq.com>","2014816656@qq.com"]18mail_host="smtp.163.com"19mail_postfix="163.com"2021def sendmail(to_list,sub,content):22me="北京-宏哥"+"<"+mail_user+"@"+mail_postfix+">"23msg=MIMEText("<a href='https://www.cnblogs.com/du-hong'><font color='red'>北京-宏哥</font></a>","html","utf-8")24msg['Subject']=sub25msg['From']=me26msg['To']=",".join(to_list)27try:28server=smtplib.SMTP()29        server.connect(mail_host)30        server.login(mail_user,mail_password)31        server.sendmail(me,to_list,msg.as_string())32        server.close()33return True34except Exceptionas e:35        print (str(e))36return False37ifsendmail(mailto_list,"标题:发送的是html格式","<a href='https://www.cnblogs.com/du-hong'>北京-宏哥</a>"):38print ("done!")39else:40print ("falsed!")

1.4 Python发送图片邮件

# coding=utf-8#1.先设置编码,utf-8可支持中英文,如上,一般放在第一行

#2.注释:包括记录创建时间,创建人,项目名称。'''Created on2019-5-9@author: 北京-宏哥

Project:学习和使用1邮箱发HTML邮件'''#3.导入模块

#"-*- coding: utf-8 -*-"import smtplibfrom email.mime.text import MIMEText

mail_user="@@@@@163.com"mail_password="@@@@"mailto_list=["1918991791<1918991791@qq.com>","2014816656@qq.com"]

mail_host="smtp.163.com"mail_postfix="163.com"def sendmail(to_list,sub,content):

    me="北京-宏哥"+"<"+mail_user+"@"+mail_postfix+">"    msg=MIMEText('<html><body><img hidefocus="true" class="index-logo-src" src="//www.baidu.com/img/bd_logo1.png" width="270" height="129" usemap="#mp"></body></html>','html','utf-8')

    msg['Subject']=sub

    msg['From']=me

    msg['To']=",".join(to_list)

    try:

        server=smtplib.SMTP()

        server.connect(mail_host)

        server.login(mail_user,mail_password)

        server.sendmail(me,to_list,msg.as_string())

        server.close()

        return True

    except Exception as e:

        print (str(e))

        return Falseifsendmail(mailto_list,"标题:发送的是HTML格式","<a href='https://www.cnblogs.com/du-hong'>北京-宏哥</a>"):

    print ("done!")else:

    print ("falsed!")

上面发邮件的几种常见的发邮件方法基本满足日常需求了。

小结

1、linux环境下提示AttributeError: module 'smtplib' has no attribute 'SMTP',Windows环境运行代码也报如下错误:

2、原因当然不是模块的问题,检查了一下拼写也没有出问题,最后在这个帖子(链接)的启发下发现,发现自己的文件命名为email.py,和模块中的函数有冲突,改名之后Linux环境邮件正常发送。

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

推荐阅读更多精彩内容