python画统计图 -> 发送QQ邮件

python画统计图 -> 发送QQ邮件

涉及点

  1. python执行命令行
  2. python画统计图
  3. 将图片插入邮件正文
  4. 将图片插入邮件附件
  5. python发送邮件

代码简介

  1. execShell方法用来执行命令(有返回)<涉及点 1>
  2. create_image方法生成统计图.<涉及点 2>
  3. create_email方法生成邮件(有返回)<涉及点 3、4>
  4. send_email方法发送邮件<涉及点 5>

代码

  • 只需修改这几个变量(my_annex_path、my_sender、my_password、my_receiver)就可以直接运行。
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
import smtplib
from email.mime.image import MIMEImage
import matplotlib.pyplot as plt
import json
import os

# 输入发件人昵称、收件人昵称、主题,正文,附件地址,附件名称生成一封邮件
def create_email(email_from, email_to, email_Subject, email_text, annex_path, annex_name):
    #生成一个空的带附件的邮件实例
    message = MIMEMultipart('related')
    #生成发件人名称(这个跟发送的邮件没有关系)
    message['From'] = Header(email_from, 'utf-8')
    #生成收件人名称(这个跟接收的邮件也没有关系)
    message['To'] = Header(email_to, 'utf-8')
    #生成邮件主题
    message['Subject'] = Header(email_Subject, 'utf-8')
    #读取附件的内容
    att1 = MIMEText(open(annex_path, 'rb').read(), 'base64', 'utf-8')
    att1["Content-Type"] = 'application/octet-stream'
    #生成附件的名称(给中文不起效果,不过不影响使用)
    att1["Content-Disposition"] = 'attachment; filename=' + annex_name

    # 插入图片 参考 https://zhuanlan.zhihu.com/p/20800785
    # 直接用python的MIMEText是无法直接支持图片格式的
    # 但MIMEText支持html格式,通过python发送html格式数据并在html中嵌入图片,这样就在邮件正文中插入图片了。
    fp = open(annex_path, 'rb')
    img = MIMEImage(fp.read())
    fp.close()
    img.add_header('Content-ID', '<image1>')
    message.attach(img)
    html = """
        <html>
    	    <head> </head>
    	    <body>
    	    	<p>图表展示:<br>
    	    		<br><img src="cid:image1"><br>
    	    	</p>
    	    </body>
        </html>
        """
    htm = MIMEText(email_text + "\n" + html, 'html', 'utf-8')
    message.attach(htm)

    message.attach(att1)
    return message

# 一个输入邮箱、密码、收件人、邮件内容发送邮件的函数
def send_email(sender, password, receiver, msg):
    try:
        server = smtplib.SMTP_SSL("smtp.qq.com", 465)  # 发件人邮箱中的SMTP服务器
        server.ehlo()
        #登录你的账号
        server.login(sender, password)# 括号中对应的是发件人邮箱账号、密码->qq邮箱是授权码
        server.sendmail(sender, receiver, msg.as_string()) # 括号中对应的是发件人邮箱账号、收件人邮箱账号(是一个列表)、邮件内容
        print("邮件发送成功")
        server.quit()
    except Exception:
        print("邮件发送失败")

# 这是个人逻辑,根据自身的数据而定
def create_image(datas, my_annex_path):
    collect = {}
    # 下面是三个列表用来放置处理后的数据(用来生成统计图)
    types = []
    capacitys = []
    changes = []
    # 解析json字符串
    jsonStr = json.loads(datas)

    # 解析汇总json数据
    for obj in jsonStr:
        # {'category': 'a', 'path': '/zzyTest/test04', 'space': '0.0498', 'changeSpace': '+0.0498'}
        category = obj["category"]
        space = obj["space"]
        changeSpace = obj["changeSpace"]
        if category in collect.keys():
            value = collect.get(category)
            values = value.split(",")
            v = str(float(space) + float(values[0])) + "," + str(float(changeSpace) + float(values[1]))
            collect[category] = v
        elif category not in collect.keys():
            collect[category] = space + "," + changeSpace

    # 把展示数据放入数组
    for k in collect.keys():
        changeNum = ""
        values = collect.get(k).split(",")
        types.append(k)
        capacitys.append(round(float(values[0]), 2))
        cn = round(float(values[1]), 2)
        if cn > 0:
            changeNum = "+" + str(cn) + "TB"
        else:
            changeNum = "-" + str((-1 * cn)) + "TB"
        changes.append(changeNum)

    # 绘制
    plt.figure(figsize=(11, 7)) # 图的长宽大小
    plt.bar(types, capacitys, width=0.5)
    plt.title('图标注')
    plt.xlabel('type')
    plt.ylabel('space(TB)')
    # 字体配置(显示中文)
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False

    # 额外在图上添加标签
    for x, y, z in zip(types, capacitys, changes):
        #  绿 #008000 红 #FF0000  可以参考这里 https://www.cnblogs.com/zoe-chang/p/11269780.html
        if z[0] == "+":
            plt.text(x, y + 0.06, "        " + str(z), ha='center', va='bottom', fontsize=10.5, color='#FF0000')
        else:
            plt.text(x, y + 0.06, "        " + str(z), ha='center', va='bottom', fontsize=10.5, color='#008000')
        plt.text(x, y * 0.5, str(y), ha='center', va='bottom', fontsize=10.5)
    # 保存图片 dpi:像素;bbox_inches:inches意思是英寸 ;注意相同命名的会替换
    plt.savefig(my_annex_path, dpi=400, bbox_inches='tight')

#  执行一些命令(curl、hdfs、……)并返回响应数据
def execShell(cmd):
    r = os.popen(cmd)
    text = r.read()
    r.close()
    return text


if __name__ == '__main__':
    my_email_from = '发件人'
    my_email_to = '收件人'
    my_email_Subject = '邮件标题'
    my_email_text = "邮件正文"
    my_annex_path = 'C:\Visio\est.png'# 指定行生成的图片路径
    my_annex_name = 'accessory_name'
    my_sender = 'xxxxxx@qq.com'  # 发件人邮箱账号
    my_password = 'htxobydgienqbbca'  # qq邮箱授权码
    my_receiver = ['yyyyy@qq.com']  # 收件人邮箱账号
    cmd = "curl -X GET --header 'Accept: application/json' 'http://127.0.0.1:7790/restful/hdfsSpace' 2>/dev/null"

    # 生产制图数据
    # datas = execShell(cmd)
    # 这里直接用样例数据,想用上面注释的那个方法的话就自行修改一下
    datas = """[
        {
            "category": "a",
            "path": "/zzyTest/test04",
            "space": "0.0498",
            "changeSpace": "+0.0498"
        },
        {
            "category": "b",
            "path": "/wsbTest/test04",
            "space": "0.0217",
            "changeSpace": "+0.0217"
        },
        {
            "category": "b",
            "path": "/wsbTest/test05",
            "space": "0.0510",
            "changeSpace": "+0.051"
        },
        {
            "category": "a",
            "path": "/wsbTest/test01",
            "space": "0.1135",
            "changeSpace": "+0.1135"
        },
        {
            "category": "a",
            "path": "/zzyTest/test01",
            "space": "0.1876",
            "changeSpace": "+0.1876"
        },
        {
            "category": "a",
            "path": "/zzyTest/test02",
            "space": "0.0653",
            "changeSpace": "+0.0653"
        },
        {
            "category": "a",
            "path": "/zzyTest/test03",
            "space": "0.0716",
            "changeSpace": "+0.0716"
        },
        {
            "category": "b",
            "path": "/wsbTest/test02",
            "space": "0.1000",
            "changeSpace": "+0.1"
        },
        {
            "category": "b",
            "path": "/wsbTest/test03",
            "space": "0.0231",
            "changeSpace": "+0.0231"
        },
        {
            "category": "d",
            "path": "/wsbTest/test03",
            "space": "0.031",
            "changeSpace": "+0.0231"
        },
        {
            "category": "d",
            "path": "/wsbTest/test03",
            "space": "0.31",
            "changeSpace": "-0.1"
        },
        {
            "category": "d",
            "path": "/wsbTest/test03",
            "space": "0.331",
            "changeSpace": "-0.41"
        },
        {
            "category": "e",
            "path": "/wsbTest/test03",
            "space": "0.31",
            "changeSpace": "-0.1"
        },
        {
            "category": "e",
            "path": "/wsbTest/test03",
            "space": "0.341",
            "changeSpace": "-0.331"
        },
        {
            "category": "e",
            "path": "/wsbTest/test03",
            "space": "0.931",
            "changeSpace": "-0.31"
        },
        {
            "category": "f",
            "path": "/wsbTest/test03",
            "space": "0.631",
            "changeSpace": "+0.31"
        },
        {
            "category": "f",
            "path": "/wsbTest/test03",
            "space": "1.31",
            "changeSpace": "+0.1"
        },
        {
            "category": "f",
            "path": "/wsbTest/test03",
            "space": "0.631",
            "changeSpace": "-0.31"
        },
        {
            "category": "g",
            "path": "/wsbTest/test03",
            "space": "0.41",
            "changeSpace": "-0.21"
        },
        {
            "category": "g",
            "path": "/wsbTest/test03",
            "space": "0.31",
            "changeSpace": "-0.21"
        },
        {
            "category": "g",
            "path": "/wsbTest/test03",
            "space": "0.61",
            "changeSpace": "-0.1"
        },
        {
            "category": "h",
            "path": "/wsbTest/test03",
            "space": "0",
            "changeSpace": "-0.0441"
        },
        {
            "category": "h",
            "path": "/wsbTest/test03",
            "space": "3.5",
            "changeSpace": "+0.011"
        },
        {
            "category": "h",
            "path": "/wsbTest/test03",
            "space": "0",
            "changeSpace": "-0.1"
        }
    ]"""
    # 生成统计图
    create_image(datas, my_annex_path)
    # 生成邮件
    my_msg = create_email(my_email_from, my_email_to, my_email_Subject,
                          my_email_text, my_annex_path, my_annex_name)
    # 发送邮件
    send_email(my_sender, my_password, my_receiver, my_msg)

参考

https://blog.csdn.net/weixin_42107474/article/details/89055356
https://zhuanlan.zhihu.com/p/20800785
https://blog.csdn.net/BF02jgtRS00XKtCx/article/details/82393284
https://www.cnblogs.com/lovealways/p/6701662.html
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值