有一個功能需求,天天在cacti上爬取昨天一成天的流量圖,並將流量圖上的min、max、average流量作成表格,用郵件發出。 (python2.7.5)php
一、須要使用的模塊html
#!/usr/bin/env python #-*- coding: UTF-8 -*- import time,datetime,cookielib,requests,sys,re,urllib2,urllib,socket,csv,heapq import smtplib import mimetypes import time from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email import encoders from email.MIMEImage import MIMEImage default_encoding = 'utf-8' if sys.getdefaultencoding() != default_encoding: reload(sys)
二、登錄cacti的函數python
def Login1(): socket.setdefaulttimeout(10) global headers headers={} cj = cookielib.CookieJar() global opener opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) # cacti使用的帳號密碼 data = urllib.urlencode( {'action':'login','login_username':'admin','login_password':'123456' }) # 打開cacti主頁 page = urllib2.Request("http://100.0.102.3/index.php", data ,headers) # 爬取頁面數據 html = opener.open(page).read() # 若是頁面數據中有graph_settings.php連接,說明登錄成功(返回1),反之登錄失敗(返回0) if re.findall("graph_settings.php",html): return 1 else: return 0
三、再定義幾個須要用到的函數服務器
# 日期轉換爲時間戳(cacti的圖片網址須要指定開始和結束時間) def datetime_timestamp(dt): time.strptime(dt, '%Y-%m-%d %H:%M:%S') s = time.mktime(time.strptime(dt, '%Y-%m-%d %H:%M:%S')) return int(s) # 將bit換算成Gbit/Mbit/Kbit(各級相差1000倍,保留2位小數) def tobit(x): if x>=1000000000: return str(round(x/1000000000,2))+'G' elif x>=1000000: return str(round(x/1000000,2))+'M' elif x>=1000: return str(round(x/1000,2))+'K' else: return str(round(x,2))
四、開始抓取圖片和csv(以下圖,圖片右邊的藍色下載箭頭就是csv)。
cookie
try: # 若是登錄成功 if Login1()==1: # 流量圖的開始時間,昨天的00:00:00 start_time=str(datetime_timestamp((datetime.datetime.today()-datetime.timedelta(days=1)).strftime('%Y-%m-%d 00:00:00'))) # 流量圖的結束時間,今天的00:00:00 end_time=str(datetime_timestamp(datetime.datetime.today().strftime('%Y-%m-%d 00:00:00'))) # 昨天一成天的流量圖網址(2687是圖片id) url1="http://100.0.102.3/graph_image.php?action=zoom&local_graph_id=2687&rra_id=0&view_type=&graph_start="+start_time+"&graph_end="+end_time # 下載圖片,保存到本地 request = urllib2.Request(url1, None ,headers) res = opener.open(request).read() f=open("/myftpdir/2687.png","wb") f.write(res) f.close() # 下載圖片對應的csv(用於讀取max、min等數值) url2="http://100.0.102.3/graph_xport.php?local_graph_id=2687&rra_id=0&view_type=&graph_start="+start_time+"&graph_end="+end_time request = urllib2.Request(url2, None ,headers) res = opener.open(request).read() f=open("/myftpdir/2687.csv","wb") f.write(res) f.close() # 讀取這個csv文件 f=open('/myftpdir/2687.csv','rb') reader = csv.reader(f) # csv保存了每5分鐘的平均上傳(outbound)和下載(inbound)速率(共288行),生成2個列表來存儲全部的上傳速率和下載速率 inbounds=[] outbounds=[] n=0 for row in reader: # 該表格的第11行到298行是速率 if n>=10 and n<=297: # 若是數據顯示NaN,則表示cacti當時獲取數據失敗,這種狀況不作存儲 # csv第1列是時間,第2列是inbound,第3列是outbound if row[1]!='NaN': inbounds.append(float(row[1])) if row[2]!='NaN': outbounds.append(float(row[2])) n+=1 # inbound平均速率=inbounds列表的全部速率總和/列表長度(就是存儲的速率個數),並換算單位 inbound_ave1=tobit(float(reduce(lambda x,y:x+y,inbounds)/len(inbounds))) # inbounds列表的最小值 inbound_min1=tobit(heapq.nsmallest(1,inbounds)[0]) # inbounds列表的最大值 inbound_max1=tobit(heapq.nlargest(1,inbounds)[0]) # 一樣方法計算outbound的平均速率、最大速率、最小速率 outbound_min1=tobit(heapq.nsmallest(1,outbounds)[0]) outbound_max1=tobit(heapq.nlargest(1,outbounds)[0]) outbound_ave1=tobit(float(reduce(lambda x,y:x+y,outbounds)/len(outbounds)))
五、發送郵件app
# 指定發件人、收件人、標題等 msg = MIMEMultipart('related') msg['From'] = "1111111@qq.com" # 郵件標題按要求作成」X年X月X日報表「 msg['Subject'] =str((datetime.datetime.today()-datetime.timedelta(days=1)).strftime('%Y'))+u'年'+str((datetime.datetime.today()-datetime.timedelta(days=1)).strftime('%m'))+u'月'+str((datetime.datetime.today()-datetime.timedelta(days=1)).strftime('%d'))+u'日報表' msg['To']="111111@qq.com" toaddrs = [msg['To']] msgAlternative = MIMEMultipart('alternative') msg.attach(msgAlternative) # 流量圖加入郵件正文 fp = open('/myftpdir/2687.png', 'rb') msgImage = MIMEImage(fp.read()) fp.close() msgImage.add_header('Content-ID', '<image1>') msg.attach(msgImage) # 郵件正文,由於要添加圖片和表格,因此不能用純文本格式,改用html格式 msgText = MIMEText(''' <h4>流量圖:</h4> <img src="cid:image1"> <br> <table border="1"> <tr> <th>出口</th> <th>最小值</th> <th>平均值</th> <th>最大值</th> </tr> <tr> <th>inbound</th> <th>%s</th> <th>%s</th> <th>%s</th> </tr> <tr> <th>outbound</th> <th>%s</th> <th>%s</th> <th>%s</th> </tr> </table> ''' % (inbound_min1,inbound_ave1,inbound_max1,outbound_min1,outbound_ave1,outbound_max1), 'html', 'utf-8') msgAlternative.attach(msgText) # 鏈接郵箱服務器 server = smtplib.SMTP() server.connect('smtp.qq.com',25) server.ehlo() server.login('111111@qq.com','123456') server.sendmail(msg['From'],toaddrs,msg.as_string()) server.quit() except: # 登錄失敗 pass
郵件內容: python2.7