PhantomJS按尺寸截取頁面,並用python發送郵件

前言:當前有個任務是要把幾個網站的日誌返回狀態碼進行彙總,用餅圖展示,並每天發送郵件。


一、分析問題

  1. 畫出餅圖,這個我用kibana給畫出來了,下面不做講解;
  2. 截取餅圖,因爲kibana是用js展示出來的,而不真的是一張jpg的圖片,如何截取你想要的圖片;
  3. 發送截圖,想到利用python發送郵件,但發出來總是以附件形式,而我想直接在郵件裏展示截圖;
  • 知道問題了,下面講具體的解決問題過程

二、安裝 PhantomJS

1. 安裝依賴包

yum install gcc gcc-c++ make git openssl-devel freetype-devel fontconfig-devel 

2. 下載 phantomjs

git clone git://github.com/ariya/phantomjs.git 

3. 編譯 phantomjs

cd phantomjs 
git checkout 1.9 
./build.sh
  • 此過程比較耗時,可以先去打個飛機,編譯完這個目錄大概有700多M

4. 測試

cat baidu.js

var page = require('webpage').create();
page.open('http://www.baidu.com', function () {
    page.render('baidu.png');
    phantom.exit();
});

運行

./phantomjs/bin/phantomjs baidu.js

可以看到本地生產的baidu.png

baidu
看,它會把整個頁面給截下來,下面我們繼續進行細緻的截圖。

三、按要求截圖

  • 先看看原網頁

kibana
我們只要中間的餅圖和它上面的一行狀態碼數量統計,

1. 改善腳本1

cat kibana.js

var page=require('webpage').create();
var address='http://log.xxx.cn/#/dashboard/file/sla.json';   // 設置url
var output='kiban.png';  // 設置保存文件名
page.viewportSize={width:1024,height:800};    // 設置查看頁面的分辨率
page.open(address,function(status){
if(status!=='success'){
console.log('Unabletoloadtheaddress!');
phantom.exit();
}else{
window.setTimeout(function(){
page.clipRect={top:170, left:10, height: 330, width: 980};  // 設置頁邊距,從而獲取想要的圖片,需要慢慢調整
page.render(output);  // 保存圖片
phantom.exit();
},20000);
}
});

運行,可以得到如下圖:

Paste_Image.png

你也可以只要中間的餅圖,爲了方便用同樣的方法獲得其他網頁的統計截圖,再次修改下腳本

2. 改善腳本2

cat kibana.js

var page=require('webpage').create();
var address = phantom.args[0];
var output = phantom.args[1];
page.viewportSize={width:1024,height:800};    // 設置查看頁面的分辨率
page.open(address,function(status){
if(status!=='success'){
console.log('Unabletoloadtheaddress!');
phantom.exit();
}else{
window.setTimeout(function(){
page.clipRect={top:170, left:10, height: 330, width: 980};  // 設置頁邊距,從而獲取想要的圖片,需要慢慢調整
page.render(output);  // 保存圖片
phantom.exit();
},20000);
}
});

如上,我們把url和文件名改成接收參數
運行:

./phantomjs/bin/phantomjs kibana.js  http://log.xxx.cn/#/dashboard/file/sla.json kibana.png

我們只需要變換url和文件名,就可以獲得其他統計圖,完成後我們把它加到郵件發出去

四、發送郵件

  • python發郵件沒啥好說的,網上有很多腳本,我也是在網上擼的腳本,剛開始郵件是能發,但是發的圖片總是以附件形式展示,而不是打開郵件就能看到截圖,在網上找了好久終於找到 Python/Perl 如何在HTML郵件正文中嵌入本地圖片,原來要先把圖片插入html頁面,然後以html形式發送郵件,最後腳本如下:
    cat send_page.py
#!/usr/bin/env python
#coding:utf8
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email import encoders
import sys
import os
from datetime import * 
# 定義函數
def send_mail(to_list, sub):
        me = mail_user + "<"+mail_user+"@"+mail_postfix+">"
        msg = MIMEMultipart()
        msg['Subject'] = sub
        msg['From'] = me
        msg['To'] = "".join(to_list)

        # 生成不同的url,並通過/root/kibana.js 生成不同的png圖片
        for i in ('node', 'mapi', 'api', 'yunying-sla'):
            os.system("/root/phantomjs/bin/phantomjs /root/kibana.js http://log.xxx.cn/#/dashboard/file/%s.json %s.png" % (i,i)) 
            #二進制模式讀取圖片,並綁定到郵件頭
            with open(i+'.png', 'rb') as fp:
                img = MIMEImage(fp.read())
                img.add_header('Content-ID', i)
                msg.attach(img)

        # kibana會收集從此刻算起前24小時的數據,我在郵件開頭記錄時間間隔,
        d = datetime.now()
        dt = d.strftime('%Y-%m-%d %H:%M:%S')
        at = (d - timedelta(1)).strftime('%Y-%m-%d %H:%M:%S')
        timezone  = at + ' ~ ' + dt

        #構造html
        html = """\
        <html>
          <body>
            <p>採集時間: """ + timezone + """</p>
  <p>
            <a href="http://log.xxx.cn/#/dashboard/file/node.json">node</a>
            </p>
            [img src="cid:node" alt="node">
            <p>
            <a href="http://log.xxx.cn/#/dashboard/file/mapi.json">mapi</a>
            </p>
            [img src="cid:mapi" alt="mapi" >
            <p>
            <a href="http://log.xxx.cn/#/dashboard/file/api.json">api</a>
            </p>
            [img src="cid:api" alt="api" >
            <p>
            <a href="http://log.xxx.cn/#/dashboard/file/yunying-sla.json">yunying</a>
            </p>
            [img src="cid:yunying-sla" alt="yunying-sla" >
          </body>
        </html>
        """
# 請把 [img 換成 <img
        context = MIMEText(html,_subtype='html',_charset='utf-8')  #定義發送的形式和編碼格式,這裏以html形式發送
        msg.attach(context) 

        try:
                send_smtp = smtplib.SMTP()
                send_smtp.connect(mail_host)
                send_smtp.login(mail_user, mail_pass)
                send_smtp.sendmail(me, to_list, msg.as_string())
                send_smtp.close()
                return True
        except Exception, e:
                print str(e)[1]
                return False
# 設置服務器名稱、用戶名、密碼以及郵件後綴
mail_host = 'smtp.xxx.com'
mail_user = '[email protected]'
mail_pass = '8888888888'
mail_postfix = "xxx.com"
#mailto_list = ["[email protected]","[email protected]"]
mailto_lists = sys.argv[1]
mailto_list = mailto_lists.split(',')   #發送多人
sub= sys.argv[2]
# send_mail
if send_mail(mailto_list, sub):
        print "Send mail succed!"
else:
        print "Send mail failed!"

運行:

python send_sla.py jianwen.lu@xxx.com "網站服務狀態sla"

由於es查詢日誌,並給kibana展示需要花點時間,所以你最好去打個飛機再來
我們收下郵件:

mail
點擊藍色字體,還可以直接去頁面看


好了,至此,做好計劃任務,等着每天發圖了,啦啦啦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章