puhua.net

View My GitHub Profile

11 August 2020

发送zabbix数据概览邮件报告

#!/usr/bin/python
# coding:utf-8

# 邮件
import smtplib
import tempfile
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

# 爬虫
# pip install bs4
import requests
from bs4 import BeautifulSoup
# zabbix api
# pip install pyzabbix
from pyzabbix import ZabbixAPI, ZabbixAPIException


class ZabbixReport:
    def __init__(self, zabbixapi):
        self.zapi = zabbixapi
        self.__server = zapi.url.replace('api_jsonrpc.php', '')
        self.__sessionid = zapi.check_authentication()["sessionid"]
        self.__path = tempfile.gettempdir()

        self.dtfrom = ''
        self.dtto = ''

        self.smtp_server = ''
        self.smtp_port = '25'
        self.sender_name = ''
        self.sender_email = ''
        self.sender_password = ''
        self.to_receivers = []
        self.cc_receivers = []
        self.__receivers = []
        self.subject = ''

    def get_screenname(self, screenid):
        screen = zapi.screen.get(screenids=screenid, output="extend")
        result = screen[0]['name']
        return result

    def get_msgbody(self, screenid):
        # url
        url = "{}screens.php".format(self.__server)
        # print(url)
        # 参数
        param = {}
        param['elementid'] = screenid
        # 设置header
        header = {}
        header['Connection'] = 'Keep-Alive'
        header[
            'User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'
        header['Cache-Control'] = 'no-cache'
        header['Accept-Language'] = 'zh-CN'
        header['Accept-Encoding'] = 'gzip'
        # 设置cookies
        cookie = {}
        cookie['zbx_sessionid'] = self.__sessionid
        try:
            # 发送请求
            response = requests.get(
                url, params=param, headers=header, cookies=cookie)
            # 如果响应状态码不是200,就抛出异常
            response.raise_for_status()
        except requests.RequestException as e:
            print(e)
        else:
            # 获得响应数据
            str_html = response.text
            soup = BeautifulSoup(str_html, 'html.parser')
            soup_select = soup.select('body > main > div.table-forms-container')
            # soup_select = soup.select('.flickerfreescreen', limit=1)
            # 移除 a标签
            for link in soup_select[0].find_all('a'):
                link.replaceWith(link.text)
            soup_select_str = str(soup_select[0]).decode('utf-8')
            msg_body_str = u"""
                <strong> 各位主管,</strong>
                <p> 今日{subject},如下圖。 </p>
                <p> 請知悉,謝謝! </p>
            """.format(subject=self.subject)
            msgbody = u"""
                <!DOCTYPE html>
                <html>
                  <head>
                    <meta charset="utf-8" />
        
                    <style type="text/css">
                      .high-bg {
                        background-color: #E97659;
                      }
        
                      .high-bg a.link-action,
                      .high-bg input[type="radio"]:checked+label {
                        color: #52190b;
                      }
        
                      .nowrap {
                        white-space: nowrap;
                      }
        
                      .wordwrap {
                        word-break: break-all;
                      }
        
                      .cursor-pointer {
                        cursor: pointer;
                      }
        
                      .table-forms-container {
                        margin: 0 0 10px 0;
                        background-color: #fff;
                        border: 1px solid #dfe4e7;
                        padding: 10px;
                        text-align: left;
                        font-size: 75%;
                      }
        
                      .table-forms-container>.ui-tabs-nav,
                      .browser-warning-container>.ui-tabs-nav {
                        margin: -10px -10px 10px -10px;
                      }
        
                      .table-forms-container {
                        display: table;
                        margin: 0;
                        padding: 0;
                        border: 0;
                      }
        
                      .screen-table {
                        background-color: #fff;
                        width: 100%;
                      }
        
                      .screen-table td {
                        padding: 2px 3px;
                      }
        
                      .screen-table .table-forms {
                        text-align: left;
                      }
        
                      .screen-table .list-table {
                        border: none;
                      }
        
                      .screen-table .list-table td {
                        text-align: left;
                        padding: 6px 5px;
                        border: none;
                        border-bottom: 1px solid #ebeef0;
                      }
        
                      .filter-container .list-table {
                        margin-bottom: -10px;
                        border: none;
                      }
        
                      .filter-container .list-table thead th {
                        color: initial;
                        padding: 8px 5px 5px 5px;
                        border-bottom-width: 1px;
                      }
        
                      .screen-table .dashbrd-widget {
                        margin: 0;
                        border: none;
                      }
        
                      .screen-table .dashbrd-widget th {
                        padding: 6px 5px;
                      }
        
                      .screen-table .dashbrd-widget-head {
                        text-align: left;
                        padding: 4px 5px;
                      }
        
                      .screen-table .dashbrd-widget-head li {
                        line-height: 2.9em;
                      }
        
                      .screen-table .dashbrd-widget-foot {
                        margin: 0;
                      }
        
                      .screen-table .nothing-to-show td {
                        text-align: center !important;
                      }
        
                      .center {
                        text-align: center;
                      }
        
                      .middle {
                        vertical-align: middle;
                      }
        
                      .dashbrd-widget-foot {
                        text-align: right;
                        color: #768d99;
                        margin: 0 10px;
                      }
        
                      .dashbrd-widget-foot li {
                        display: inline-block;
                        padding: 8px 0 8px 13px;
                      }
        
                      .flickerfreescreen {
                        position: relative;
                        overflow: hidden;
                      }
        
                      .dashbrd-widget-head {
                        position: relative;
                        padding: 8px 60px 8px 10px;
                      }
        
                      .dashbrd-widget-head h4 {
                        color: #3c5563;
                        font-weight: bold;
                      }
        
                      .dashbrd-widget-head ul {
                        position: absolute;
                        top: 0;
                        right: 0;
                      }
        
                      .dashbrd-widget-head ul li {
                        display: block;
                        float: left;
                        padding: 0;
                      }
        
                      .dashbrd-widget-head ul li select {
                        margin: 4px 0;
                      }
        
                      .overlay-dialogue .dashbrd-widget-head {
                        margin: -10px -10px 6px -10px;
                      }
        
                      .vertical_rotation_inner {
                        white-space: nowrap;
                        -webkit-transform: rotate(270deg);
                        -moz-transform: rotate(270deg);
                        -ms-transform: rotate(270deg);
                        transform: rotate(270deg);
                      }
        
                      .list-table .list-table-footer {
                        border-bottom: none;
                        color: #768d99;
                        text-align: right;
                      }
                    </style>
        
        
                  </head>
                  <body>
                    <!--REPLACE1-->
                    <!--REPLACE2-->
                  </body>
                </html>        
            """
            msgbody = msgbody.replace("<!--REPLACE1-->", msg_body_str)
            msgbody = msgbody.replace("<!--REPLACE2-->", soup_select_str)
            html_sub = MIMEText(msgbody, 'html', 'utf-8')
            return html_sub

    def get_message(self, screenid):
        # 设置总的邮件体对象,对象类型为mixed
        msg_root = MIMEMultipart('mixed')

        # 邮件添加的头尾信息等
        self.subject = self.get_screenname(screenid)
        msg_root['From'] = Header('%s<%s>' % (
            self.sender_name, self.sender_email), 'utf-8')
        msg_root['To'] = ','.join(self.to_receivers)
        msg_root['Cc'] = ','.join(self.cc_receivers)
        msg_root['Subject'] = Header(self.subject, 'utf-8')

        # 构造超文本
        html_sub = self.get_msgbody(screenid)

        # 把构造的内容写到邮件体中
        msg_root.attach(html_sub)
        return msg_root

    def send_mail(self, message_obj):
        try:
            self.__receivers = self.to_receivers + self.cc_receivers
            smtp_obj = smtplib.SMTP(self.smtp_server, self.smtp_port)
            smtp_obj.login(self.sender_email, self.sender_password)
            smtp_obj.sendmail(self.sender_email,
                              self.__receivers, message_obj.as_string())
            smtp_obj.quit()
            print('%s sendemail successful!' % self.subject)
        except Exception as e:
            print('%s sendemail failed' % self.subject)
            print(e)


if __name__ == "__main__":
    # 如果脚本未获取到外部参数,则使用脚本内部设定的参数
    screenids = ['33']
    to_receivers = ['[email protected]']
    cc_receivers = []

    # 信息
    server = 'http://localhost/zabbix'
    username = 'Admin'
    password = 'zabbix'

    # 登入
    zapi = ZabbixAPI(server)
    try:
        zapi.login(username, password)
    except ZabbixAPIException as e:
        print(e)
    else:
        zr = ZabbixReport(zapi)
        zr.smtp_server = 'localhost'
        zr.sender_name = 'zabbix'
        zr.sender_email = 'zabbix@localhost'
        zr.sender_password = 'password'
        zr.to_receivers = to_receivers
        zr.cc_receivers = cc_receivers

        for screenid in screenids:
            # 构造邮件
            msg = zr.get_message(screenid)

            # 发送邮件
            zr.send_mail(msg)

        print("Done.")