环境

虽说就发邮件这么个小事,很容易兼容Python2, Python3, 但是大家还是拥抱Python3吧, 我这里没有做python2的兼容写法,所以需要python3以上。

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:1097524789

邮件的格式

邮件的格式主要就两种: plain和html

plain就像一个普通的文本, 没有格式。

html就如其名, 是html的格式,相当于一个邮件就是一个 静态 的网页,这样的话可玩性就很高了,你可以通过css控制表现形式.

注意: 这里的css虽然语法一样,但,是否与浏览器渲染结果完全一致, 是不一定的。

那么可能有人要问了,我要发一个动态的网页怎么办? 发个链接呀

邮箱账号

无论是QQ邮箱抑或网易邮箱都是没有问题的,重要的是有一个可以通过smtp服务器发送邮件的账户名及密码,这里大家百度吧。

发送邮件的代码

因为发送邮件的代码在下面每个步骤都是一样的所以线贴出来

def send_email(msg, mail_to, smtp_host, smtp_username, smtp_password, subject, from_):msg["Subject"] = Header(subject, "utf-8")msg["From"] = Header(from_, "utf-8")if not isinstance(mail_to, list):mail_to = [mail_to]msg["To"] = COMMASPACE.join(mail_to)try:print("准备连接smtp邮件服务器: %s" % smtp_host)client = smtplib.SMTP(smtp_host)print("连接成功")# client = smtplib.SMTP("localhost")# client.set_debuglevel(1)# print(self.mail_user, self.mail_pass)client.login(smtp_username, smtp_password)print("登录成功")# print("=====>", self.mail_from, mail_to)print("通过邮箱[%s]发送邮件给 %s" % (smtp_username, COMMASPACE.join(mail_to)))client.sendmail(smtp_username, mail_to, msg.as_string())print("发送成功...")return Trueexcept Exception:print("发送邮件失败")finally:client.quit()

如果遇到邮件发送的问题可以将client.set_debuglevel(1)的注释取消,这样会显示足够多的debug信息用于排查问题。

发送本地图片

这里发送图片的意思是指, 图片内嵌在邮件中而不是以附件的形式出现。

效果如下:

代码如下:

EMAIL_IMAGE_TEMPLATE = """<html>
<head>
<title>Page Title</title>
</head>
<body>
<h3>这是一张图片</h3>
<p><img src="cid:{{image_name}}" height="112" width="200" ></p>
</body>
</html>
"""def create_image_eamil_contant(fp):tpl = Template(EMAIL_IMAGE_TEMPLATE)if not path.exists(fp):sys.exit("要发送的本地图片不存在")msg = MIMEMultipart("related")image_name = "demo"with open(fp, "rb") as rf:mime_image = MIMEImage(rf.read())# 注意: 一定需要<>括号mime_image.add_header("Content-ID", "<%s>" % image_name)msg.attach(mime_image)# 渲染邮件文本内容text = tpl.render(image_name=image_name)msg_alternative = MIMEMultipart("alternative")msg_alternative.attach(MIMEText(text, "html", "utf-8"))msg.attach(msg_alternative)return msg

如果你使用过python的web框架,你对文本的渲染一定不陌生,因为大多数web框架都支持文本渲染,这里使用的jinja2.

发送程序生成的照片

其实这里跟上面没什么区别的,唯一的区别就是是否保存在本地,既然能发送本地图片,我就先保存到本地然后再按照上面的方式不久可以了么? 首先这个方法是没有问题的,不过多了一次IO, 能在内存中解决的事为什么要放到本地呢?

这种情况主要是应对回去图片的方式是从其他接口获取到的,或者实时生成的时候。虽然很简单,但觉得说说也挺有意思的。

这里的模拟方式是假设在网上获取到了多张base64编码的图片,需要将其组合在一起,然后在不保存在本地情况下直接发送这张照片。

这个base64编码的图片已经保存在本地了,名字是demo_base64.txt

效果如下:

代码如下:

EMAIL_ONLINE_IMAGE_TEMPLATE = """<html>
<head>
<title>Page Title</title>
</head>
<body>
<h3>这是一张图片</h3>
<p><img src="cid:{{image_name}}" ></p>
</body>
</html>
"""def create_online_image_content():from PIL import Imagetpl = Template(EMAIL_ONLINE_IMAGE_TEMPLATE)fp = "demo_base64.txt"if not path.exists(fp):sys.exit("要发送的base64编码的图片不存在")msg = MIMEMultipart("related")image_name = "demo"with open(fp, "rb") as rf:base64_data = rf.read()img_data = base64.b64decode(base64_data)# 因为open方法需要一个file-like文件对象,而我们解码后的对象类型是bytes类型# bytes类型没有文件对象的read, close方法,所以我们需要通过BytesIO对象包装一下,它会返回一个file-like文件对象img = Image.open(BytesIO(img_data))img_width, img_height = img.sizerepeat_times = 5# compose imagesret_img  = Image.new(img.mode, (img_width, img_height * repeat_times))for index in range(repeat_times):ret_img.paste(img, box=(0, index * img_height))# 因为MIMEImage需要一个bytes对象,所以们需要获取图片编码后的二进制数据而不是图片的array数据img_bytes = BytesIO()# 如果不指定图片格式,会因为没有文件名而报错ret_img.save(img_bytes, "png")mime_image = MIMEImage(img_bytes.getvalue())# 注意: 一定需要<>括号mime_image.add_header("Content-ID", "<%s>" % image_name)msg.attach(mime_image)# 渲染邮件文本内容text = tpl.render(image_name=image_name)msg_alternative = MIMEMultipart("alternative")msg_alternative.attach(MIMEText(text, "html", "utf-8"))msg.attach(msg_alternative)return msg

这里很有意思一点是用BytesIO模拟file-like对象。这里需要安装PIL哦

发送一个带样式的静态网页

前面的代码已经足够说明图片怎么发了,这里通过一个写了css样式的表格进行演示

效果如下:

代码如下:

EMAIL_TEMPLATE = """<html>
<head><style type="text/css">table{border-collapse: collapse;margin: 0 auto;text-align: center;}table td, table th{border: 1px solid #cad9ea;color: #666;height: 30px;}table thead th{background-color: #CCE8EB;width: 100px;}table tr:nth-child(odd){background: #fff;}table tr:nth-child(even){background: #F5FAFA;}</style>
</head>
<body>
<p>一共有以下{{record_size}}条数据</p>
<table width="90%" class="table"><thead><tr>{% for label in labels %}<th>{{label}}</th>{% endfor %}</tr></thead><tbody>
{% for item in items %}<tr>{% for value in item %}<td>{{value}}</td>{% endfor %}</tr>
{% endfor %}</tbody>
</table>
</html>"""def create_html_content():tpl = Template(EMAIL_TEMPLATE)record_size = 10label_size = 5labels = ["label-%s" % i for i in range(label_size)]items = []for _ in range(record_size):item = ["item-%s" % value_index for value_index in range(label_size)]items.append(item)text = tpl.render(record_size=record_size, items=items, labels=labels)msg = MIMEText(text, "html", "utf-8")return msg

源代码地址

https://github.com/youerning/blog/tree/master/sendmail

如果期待后续文章可以关注我的微信公众号(又耳笔记),头条号(又耳笔记),github.

后记

其实发送一个附件也是不错的方式,比如发送一个生成的PDF, PDF是一个很棒的文件格式。但是PDF暂时没用到,以后有机会再说吧。最后要注意的是,手机端的显示效果跟电脑网页版的显示效果是不一样的。

用Python发一封图文并茂的邮件 荐相关推荐

  1. python怎么发图文_用Python发一封图文并茂的邮件

    最近使用了不少通讯工具的接口, 比如企业微信机器人,钉钉,微信公众号的接口(未认证的订阅公众号),相对于邮件来说,它们的表现形式太弱.比如没有更丰富的版本方式.当然了,并不是说表现形式越棒就是约好的通 ...

  2. python邮件图片加密软件_用Python发一封图文并茂的邮件

    最近使用了不少通讯工具的接口, 比如企业微信机器人,钉钉,微信公众号的接口(未认证的订阅公众号),相对于邮件来说,它们的表现形式太弱.比如没有更丰富的版本方式.当然了,并不是说表现形式越棒就是约好的通 ...

  3. 裁缝式开发:用MATLAB批量发送一封图文并茂的邮件

    问题背景 前几天,女朋友公司要求她周末加班发送宣传推广邮件给高校老师,而我才知晓之前她们发送邮件全靠手动-目前待发名单至少有三千人,而现在才发了一百多封,我的心情如下 为了能够不加班周末去放风筝,于是 ...

  4. 教你撩妹,每天给小姐姐发一封暖心邮件

    写在前面 自从用邮箱注册了很多账号后,便会收到诸如以下类似的邮件,刚开始还以为是一张图片,后来仔细一看不是图片呀,好像还是 HTML 呀,于是好奇宝宝我 Google 一下,查阅多篇资料后总结出怎么用 ...

  5. 简单三步,用 Python 发邮件

    2019独角兽企业重金招聘Python工程师标准>>> 0. 前言 发送电子邮件是个很常见的开发需求.比如你写了个监控天气的脚本,发现第二天要下雨,或者网站上关注的某个商品降价了,就 ...

  6. crossin的编程教室python入门_简单三步,用 Python 发邮件

    0. 前言 发送电子邮件是个很常见的开发需求.比如你写了个监控天气的脚本,发现第二天要下雨,或者网站上关注的某个商品降价了,就可以发个邮件到邮箱来提醒自己. 使用 Python 脚本发送邮件并不复杂. ...

  7. python发邮件图片太长显示不出来_小白入门,用python 发送定时邮件,将Dataframe转为邮件正文,链接显示为图片...

    在实际工作中,我们常常会遇到定时发送邮件的任务,基于我的实践,分享给大家,也许一篇文章写不完,就先列个目录. 本文想要解决的问题: 用python构造一封邮件,并设置定时发送出去.往往,这只是最低级的 ...

  8. python发邮件附件带变量_Python 第17关——邮件还能这样发(QQ邮箱)!

    完成一个项目的流程 1.明确项目目标 2.分解过程.拆解项目 3.逐步执行.代码实现 目标:Python群发邮件 目标:学会学习新模块 掌握[学习模块的方式]→掌握学习新知识的方式 版本1.0:学习模 ...

  9. Python:如何方便地用Python发outlook邮件

    背景 单位有自动定时邮件需求,而Windows自带的定时任务不好用,不灵活,于是自己用Python写. 重点库 outlook邮件库:exchangelib 定时跑批的库:schedule 完整源码 ...

最新文章

  1. 【死磕JVM】五年 该知道JVM加载机制了!
  2. 缩进动画Scaleanimation的一个小示例
  3. 【NLP】基于深度学习的文本分类应用
  4. 最短无序连续子数组—leetcode581
  5. RabbitMQ消息追踪之rabbitmq_tracing
  6. WindowsPhone 7 页面导航和虚拟路径、导航传值
  7. 在windows上Matlab 编译MatConvNet
  8. c语言静态成员变量重名会怎么样,C++中静态成员函数与静态成员变量(static )...
  9. 领导看了我写的关闭超时订单,让我出门左转!
  10. python性能测试台_性能测试平台效率优化的一次经验(python版)
  11. Android开发学习之以CameraAPI方式实现相机功能(二)——相机功能配置
  12. fiddler如何伪造referrer_Fiddler抓包神器带你遨游网络,叱咤风云,为所欲为
  13. 富士胶片携数据磁带亮相大数据产业博览会
  14. go项目实战 <微信公众号后台开发>(一、获取token)
  15. B2c运营方法,b2c商城系统源码
  16. Java多线程系列--【JUC集合04】- ConcurrentHashMap
  17. 06.变革、变革、再变革
  18. python读二进制文件
  19. 网贷黑名单查询,通过身份证号,或者手机号查询自己的网贷情况。
  20. IT服务管理指标体系与报表体系

热门文章

  1. MNS消息服务计费处理参考
  2. UserInfoActivity用户图像修改和退出登录
  3. 黑马程序员--C语言基础之--sizeof()运算符的使用以及注意
  4. Objective-C 的动态提示和技巧
  5. oracle基本的操作
  6. web前端黑客技术揭秘 读书笔记
  7. 面试官系统精讲Java源码及大厂真题 - 34 只求问倒:连环相扣系列锁面试题
  8. DreamFacotry 第4章 如何保护REST API
  9. 【11.18总结】从SAML出发在重定向中发现的XSS漏洞
  10. JDK1.8 中 ConcurrentHashMap源码分析(一)容器初始化