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

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

简介



本篇文章与前边没有多大关联,就是对前边有关发邮件的总结和梳理。在写脚本时,放到后台运行,想知道执行情况,会通过邮件、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服务器连接


看下官方给的示例:


1232840-20190508153251751-2017271717.png


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


我这里测试使用本地的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)
 {}


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


1232840-20200707145902192-1249892968.png


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


1.1 Python发送邮件并抄送


 #!/usr/bin/python
  # -*- coding: utf-8 -*-
  import smtplib
  def sendMail(body):
     smtp_server = 'smtp.163.com'
      from_mail = 'hongge@163.com'
      mail_pass = 'xxx'
      to_mail = ['xxx@qq.com', 'xxx@163.com']
      cc_mail = ['hongge@xxx.com']
     from_name = 'monitor'
     subject = u'监控'.encode('gbk')   # 以gbk编码发送,一般邮件客户端都能识别
 #     msg = '''\
 # From: %s <%s>
 # To: %s
 # Subject: %s
 # %s''' %(from_name, from_mail, to_mail_str, subject, body)  # 这种方式必须将邮件头信息靠左,也就是每行开头不能用空格,否则报SMTP 554
    mail = [
       "From: %s <%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!")


1232840-20190509132331603-729145739.png


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

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


1232840-20190509132628995-1110170050.png


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


1232840-20190509133325318-1775180628.png


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


基本的格式就是这样的!


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


 # coding=utf-8
  #1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
  #2.注释:包括记录创建时间,创建人,项目名称。
  '''
  Created on 2019-5-9
  @author: 北京-宏哥
  Project:学习和使用邮箱发带有附件邮件
'''
 #3.导入模块
 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
 def send_mail(file_new):
     #-----------1.跟发件相关的参数------
     smtpserver = 'smtp.mxhichina.com'                #发件服务器
     port = 0                      #端口
     username = 'noreply@cxx.cn'  #发件箱用户名
     password = 'xx@@123'        #发件箱密码
     sender = 'noreply@cxx.cn'    #发件人邮箱
     receiver = ['hongge@cedex.cn','1918991791@qq.com'] #收件人邮箱
     # ----------2.编辑邮件的内容------
     #读文件内容
     f = open(file_new, 'rb')
     mail_body = f.read()
     f.close()
     # 邮件正文是MIMEText
     body = MIMEText(mail_body, 'html', 'utf-8')
     # 邮件对象
     msg = MIMEMultipart()
    msg['Subject'] = Header("自动化测试报告", 'utf-8').encode()#主题
     msg['From'] = Header(u'测试机 <%s>'%sender)                #发件人
    msg['To'] = Header(u'测试负责人 <%s>'%receiver)            #收件人
     msg['To'] = ';'.join(receiver)
     msg.attach(body)
     # # MIMEBase表示附件的对象
     att = MIMEText(mail_body, "base64", "utf-8")
     att["Content-Type"] = "application/octet-stream"
     # filename是显示附件名字
     att["Content-Disposition"] = 'attachment; filename="test_report.html"'
     msg.attach(att)
     # ----------3.发送邮件------
     try:
         smtp = smtplib.SMTP()
         smtp.connect(smtpserver)  # 连服务器
         smtp.login(sender, password)
     except:
         smtp = smtplib.SMTP_SSL(smtpserver, port)
         smtp.login(sender, password)  # 登录
     smtp.sendmail(sender, receiver, msg.as_string())  # 发送
     smtp.quit()
 if __name__ == "__main__":
     #本地文件的路径
     att_path= r'E:\pythontest\text.txt'
     send_mail(att_path)


1232840-20190509154743960-1776799402.png

 

1.3 Python发送HTML邮件

 # coding=utf-8
  #1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
  #2.注释:包括记录创建时间,创建人,项目名称。
  '''
  Created on 2019-5-9
  @author: 北京-宏哥
  Project:学习和使用邮箱发HTML邮件
  '''
 #3.导入模块
 #"-*- coding: utf-8 -*-"
 import smtplib
 from email.mime.text import MIMEText
 mail_user="XXX@163.com"
 mail_password="******q1125"
 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("<a href='https://www.cnblogs.com/du-hong'><font color='red'>北京-宏哥</font></a>","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 False
 if sendmail(mailto_list,"标题:发送的是html格式","<a href='https://www.cnblogs.com/du-hong'>北京-宏哥</a>"):
     print ("done!")
 else:
     print ("falsed!")


1232840-20190509154743960-1776799402.png


1.4 Python发送图片邮件

# coding=utf-8
#1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
#2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2019-5-9
@author: 北京-宏哥
Project:学习和使用1邮箱发HTML邮件
'''
#3.导入模块
#"-*- coding: utf-8 -*-"
import smtplib
from 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 False
if sendmail(mailto_list,"标题:发送的是HTML格式","<a href='https://www.cnblogs.com/du-hong'>北京-宏哥</a>"):
    print ("done!")
else:
    print ("falsed!")


1232840-20190509153006765-689290673.png


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


小结



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


1232840-20190508162011243-816651460.png


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

相关文章
|
6天前
|
搜索推荐 Python
使用Python自动化生成物业通知单
本文介绍如何使用Python结合Pandas和python-docx库自动化生成物业通知单。通过读取Excel数据并填充至Word模板,实现高效准确的通知单批量制作。包括环境准备、代码解析及效果展示,适用于物业管理场景。
44 14
|
10天前
|
数据采集 数据可视化 数据挖掘
利用Python自动化处理Excel数据:从基础到进阶####
本文旨在为读者提供一个全面的指南,通过Python编程语言实现Excel数据的自动化处理。无论你是初学者还是有经验的开发者,本文都将帮助你掌握Pandas和openpyxl这两个强大的库,从而提升数据处理的效率和准确性。我们将从环境设置开始,逐步深入到数据读取、清洗、分析和可视化等各个环节,最终实现一个实际的自动化项目案例。 ####
|
11天前
|
数据采集 存储 XML
Python爬虫:深入探索1688关键词接口获取之道
在数字化经济中,数据尤其在电商领域的价值日益凸显。1688作为中国领先的B2B平台,其关键词接口对商家至关重要。本文介绍如何通过Python爬虫技术,合法合规地获取1688关键词接口,助力商家洞察市场趋势,优化营销策略。
|
1天前
|
数据采集 存储 API
利用Python爬虫获取1688关键词接口全攻略
本文介绍如何使用Python爬虫技术合法合规地获取1688关键词接口数据,包括环境准备、注册1688开发者账号、获取Access Token、构建请求URL、发送API请求、解析HTML及数据处理存储等步骤,强调遵守法律法规和合理使用爬虫技术的重要性。
|
11天前
|
Android开发 开发者 Python
通过标签清理微信好友:Python自动化脚本解析
微信已成为日常生活中的重要社交工具,但随着使用时间增长,好友列表可能变得臃肿。本文介绍了一个基于 Python 的自动化脚本,利用 `uiautomator2` 库,通过模拟用户操作实现根据标签批量清理微信好友的功能。脚本包括环境准备、类定义、方法实现等部分,详细解析了如何通过标签筛选并删除好友,适合需要批量管理微信好友的用户。
22 7
|
10天前
|
安全 API 文件存储
Yagmail邮件发送库:如何用Python实现自动化邮件营销?
本文详细介绍了如何使用Yagmail库实现自动化邮件营销。Yagmail是一个简洁强大的Python库,能简化邮件发送流程,支持文本、HTML邮件及附件发送,适用于数字营销场景。文章涵盖了Yagmail的基本使用、高级功能、案例分析及最佳实践,帮助读者轻松上手。
21 4
|
9天前
|
敏捷开发 测试技术 持续交付
自动化测试之美:从零开始搭建你的Python测试框架
在软件开发的马拉松赛道上,自动化测试是那个能让你保持节奏、避免跌宕起伏的神奇小助手。本文将带你走进自动化测试的世界,用Python这把钥匙,解锁高效、可靠的测试框架之门。你将学会如何步步为营,构建属于自己的测试庇护所,让代码质量成为晨跑时清新的空气,而不是雾霾中的忧虑。让我们一起摆脱手动测试的繁琐枷锁,拥抱自动化带来的自由吧!
|
2月前
|
机器学习/深度学习 人工智能 运维
构建高效运维体系:从自动化到智能化的演进
本文探讨了如何通过自动化和智能化手段,提升IT运维效率与质量。首先介绍了自动化在简化操作、减少错误中的作用;然后阐述了智能化技术如AI在预测故障、优化资源中的应用;最后讨论了如何构建一个既自动化又智能的运维体系,以实现高效、稳定和安全的IT环境。
73 4
|
2月前
|
运维 Linux Apache
,自动化运维成为现代IT基础设施的关键部分。Puppet是一款强大的自动化运维工具
【10月更文挑战第7天】随着云计算和容器化技术的发展,自动化运维成为现代IT基础设施的关键部分。Puppet是一款强大的自动化运维工具,通过定义资源状态和关系,确保系统始终处于期望配置状态。本文介绍Puppet的基本概念、安装配置及使用示例,帮助读者快速掌握Puppet,实现高效自动化运维。
63 4
|
14天前
|
机器学习/深度学习 运维 监控
智能化运维:从自动化到AIOps的演进之路####
本文深入探讨了IT运维领域如何由传统手工操作逐步迈向高度自动化,并进一步向智能化运维(AIOps)转型的过程。不同于常规摘要仅概述内容要点,本摘要将直接引入一个核心观点:随着云计算、大数据及人工智能技术的飞速发展,智能化运维已成为提升企业IT系统稳定性与效率的关键驱动力。文章详细阐述了自动化工具的应用现状、面临的挑战以及AIOps如何通过预测性分析和智能决策支持,实现运维工作的质变,引领读者思考未来运维模式的发展趋势。 ####