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

最近使用了不少通讯工具的接口, 比如企业微信机器人,钉钉,微信公众号的接口(未认证的订阅公众号),相对于邮件来说,它们的表现形式太弱。比如没有更丰富的版本方式。当然了,并不是说表现形式越棒就是约好的通知手段,这个依个人情况而定,而我恰恰需要比较丰富的表现形式,最终还是回到了邮件,邮件真香!

很多人学习python,不知道从何学起。

很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。

很多已经做案例的人,却不知道如何去学习更加高深的知识。

那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!

QQ群:101677771

而个人微信号的接口我没有合适的微信号可以登录,如果网页版微信没有被封的话,我想这个是表现形式与消息时效性结合的最好的方式。

环境

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

邮件的格式

邮件的格式主要就两种: 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 True

except Exception:

print("发送邮件失败")

finally:

client.quit()

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

发送本地图片

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

效果如下:

代码如下:

EMAIL_IMAGE_TEMPLATE = """

Page Title

这是一张图片

"""

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", "" % 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 = """

Page Title

这是一张图片

"""

def create_online_image_content():

from PIL import Image

tpl = 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.size

repeat_times = 5

# compose images

ret_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", "" % 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 = """

{

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;

}

一共有以下{{record_size}}条数据

{% for label in labels %}

{{label}}

{% endfor %}

{% for item in items %}

{% for value in item %}

{{value}}

{% endfor %}

{% endfor %}

"""

def create_html_content():

tpl = Template(EMAIL_TEMPLATE)

record_size = 10

label_size = 5

labels = ["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

源代码地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/564512.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring基于Annotation装配Bean

在 Spring 中&#xff0c;尽管使用 XML 配置文件可以实现 Bean 的装配工作&#xff0c;但如果应用中 Bean 的数量较多&#xff0c;会导致 XML 配置文件过于臃肿&#xff0c;从而给维护和升级带来一定的困难。 Java 从 JDK 5.0 以后&#xff0c;提供了 Annotation&#xff08;注…

用java写米与英尺,JAVA 英制变换(英尺与英寸)

JAVA 英制转换(英尺与英寸)系统实际业务中&#xff0c;还有些外国船舶水尺用的英制计算单位。写了一个简单的 英尺与英寸的转换 。英尺 --> 英寸 的转换&#xff1a;public class FeetToInch {/*** param args*/public static void main(String[] args) {String aa FeetTo…

swiper鼠标hover停止自动轮播_swiper滑块组件

相信大家在平常购物的时候都会看到轮播图&#xff0c;轮播图里面播放的是热门商品的信息。在小程序里面我们可以通过swiper滑动视图容器组件来实现&#xff0c;让我们一起来看下swiper组件都有哪些属性&#xff1a;我们看到可以通过一些属性给视图容器增加一些指示点&#xff0…

Spring自动装配Bean

除了使用 XML 和 Annotation 的方式装配 Bean 以外&#xff0c;还有一种常用的装配方式——自动装配。自动装配就是指 Spring 容器可以自动装配&#xff08;autowire&#xff09;相互协作的 Bean 之间的关联关系&#xff0c;将一个 Bean 注入其他 Bean 的 Property 中。 要使用…

Spring AOP是什么?

面向切面编程&#xff08;AOP&#xff09;和面向对象编程&#xff08;OOP&#xff09;类似&#xff0c;也是一种编程模式。Spring AOP 是基于 AOP 编程模式的一个框架&#xff0c;它的使用有效减少了系统间的重复代码&#xff0c;达到了模块间的松耦合目的。 AOP 的全称是“As…

java算法概述,Java数据结构与算法基础(一)概述与线性结构

Java数据结构与算法基础(二)递归算法Java数据结构与算法基础(一)概述与线性结构学习目的&#xff1a;为了能更顺畅的读很多底层API代码和拓宽解决问题的思路一、数据结构概述1.数据结构是什么&#xff1f;数据与数据之间的关系2.数据结构的分类&#xff1a;存储结构分类&#x…

kmeans python自定义初始聚类中心_机器学习-KMeans聚类 K值以及初始类簇中心点的选取...

本文主要基于Anand Rajaraman和Jeffrey David Ullman合著&#xff0c;王斌翻译的《大数据-互联网大规模数据挖掘与分布式处理》一书。KMeans算法是最常用的聚类算法&#xff0c;主要思想是:在给定K值和K个初始类簇中心点的情况下&#xff0c;把每个点(亦即数据记录)分到离其最近…

java鬼剑士觉醒,DNF新觉醒装扮,男鬼剑士帅气无比!

在DNF这个游戏中&#xff0c;时装作为游戏的一大氪点&#xff0c;相信这几天的奇迹缝纫机活动也让大家了解到了时装到底多么的烧钱&#xff01;而也因为这次的活动&#xff0c;时装可以说达到了饱和状态了&#xff0c;估计短时间之内魔盒里不会再出现追忆时装了&#xff01;虽然…

Spring JDK动态代理

JDK 动态代理是通过 JDK 中的 java.lang.reflect.Proxy 类实现的。下面通过具体的案例演示 JDK 动态代理的使用。 1. 创建项目 在 MyEclipse 中创建一个名称为 spring 的 Web 项目&#xff0c;将 Spring 支持和依赖的 JAR 包复制到 Web 项目的 WEB-INF/lib 目录中&#xff0c;…

澄海哪里学机器人编程_少年学机器人编程

​当今社会&#xff0c;唯有能者居之&#xff0c;说的是有技能在手的人可以立足于职场&#xff0c;格物斯坦表示&#xff1a;现代化的教育方式有很多&#xff0c;其中有一种机器人编程教育模式&#xff0c;青少年们学好了&#xff0c;以后中考、高考核就业比同龄人更有优势了。…

Spring CGLlB动态代理

JDK 动态代理使用起来非常简单&#xff0c;但是有一定的局限性&#xff0c;这是因为 JDK 动态代理必须要实现一个或多个接口&#xff0c;如果不希望实现接口&#xff0c;则可以使用 CGLIB 代理。 CGLIB&#xff08;Code Generation Library&#xff09;是一个高性能开源的代码…

更新fielddata为true_在pytorch中停止梯度流的若干办法,避免不必要模块的参数更新...

在pytorch中停止梯度流的若干办法&#xff0c;避免不必要模块的参数更新2020/4/11 FesianXu前言在现在的深度模型软件框架中&#xff0c;如TensorFlow和PyTorch等等&#xff0c;都是实现了自动求导机制的。在深度学习中&#xff0c;有时候我们需要对某些模块的梯度流进行精确地…

php 自动切图,前端工程师技能之photoshop巧用系列扩展篇自动切图

目录[1]初始设置 [2]自动切图前面的话随着photoshop版本的不断升级&#xff0c;软件本身增加了很多新的功能&#xff0c;也为切图工作增加了很多的便利。photoshop最新的版本新增了自动切图功能&#xff0c;本文将详细介绍photoshop的这个新功能初始设置当然首先还是要进行一些…

Spring通知类型及使用ProxyFactoryBean创建AOP代理

Spring 通知类型 通知&#xff08;Advice&#xff09;其实就是对目标切入点进行增强的内容&#xff0c;Spring AOP 为通知&#xff08;Advice&#xff09;提供了 org.aopalliance.aop.Advice 接口。 Spring 通知按照在目标类方法的连接点位置&#xff0c;可以分为以下五种类型…

matlab二维谐振子,基于有限差分法求解的二维谐振子的MATLAB程序如下。哪位大神能帮我做个注明啊,完全看不懂啊,,急...

基于有限差分法求解的二维谐振子的MATLAB程序如下。哪位大神能帮我做个注明啊&#xff0c;完全看不懂啊&#xff0c;&#xff0c;急0____丿呆呆丶2017.04.15浏览20次分享举报tic clc clear L20; W20; N20; M20; hxL/(2*N); hyW/(2*M); Szeros((2*M-1)*(2*N-1)); for m1:2*M-1 D…

typescript get方法_.NET手撸绘制TypeScript类图——上篇

.NET手撸绘制TypeScript类图——上篇近年来随着交互界面的精细化&#xff0c;TypeScript越来越流行&#xff0c;前端的设计也越来复杂&#xff0c;而类图正是用简单的箭头和方块&#xff0c;反映对象与对象之间关系/依赖的好方式。许多工具都能生成C#类图&#xff0c;有些工具也…

Spring使用AspectJ开发AOP

AspectJ 是一个基于 Java 语言的 AOP 框架&#xff0c;它扩展了 Java 语言。Spring 2.0 以后&#xff0c;新增了对 AspectJ 方式的支持&#xff0c;新版本的 Spring 框架&#xff0c;建议使用 AspectJ 方式开发 AOP。 使用 AspectJ 开发 AOP 通常有两种方式&#xff1a; 基于 …

unicode解码php,PHP解码unicode编码的中文字符

问题背景&#xff1a;晚上在抓取某网站数据&#xff0c;结果在数据包中发现了这么一串编码的数据&#xff1a;"......\u65b0\u6d6a\u5fae\u535a......如何解码unicode编码的字符&#xff1f;【好使】 - PHP网站开发 - 【开源与分享】每日最新博客在置顶博客之后解决方案&a…

python协成_Python协程技术的演进

引言1.1. 存储器山存储器山是 Randal Bryant 在《深入理解计算机系统》一书中提出的概念。基于成本、效率的考量&#xff0c;计算机存储器被设计成多级金字塔结构&#xff0c;塔顶是速度最快、成本最高的 CPU 内部的寄存器(一般几 KB)与高速缓存&#xff0c;塔底是成本最低、速…

matlab特征方程的根,MATLAB 求解特征方程的根轨迹图稳定性分析

原文&#xff1a;http://tecdat.cn/?p3871根轨迹分析在下文中&#xff0c;我们提供了用于根轨迹分析的强大MATLAB命令的简要描述。读者可能想知道为什么当强大的MATLAB命令可用时&#xff0c;教师强调学习手工计算。对于给定的一组开环极点和零点&#xff0c;MATLAB立即绘制根…