目的是截图,截昨天的几台服务器的流量图,不是取数据写入文件。
步骤:selenium打开cacti网站并登录,点击选择到对应的图形树,遍历点击机器需要抓取的流量图(我所抓取的几台服务器都只保留了一张网卡流量图,没监控cpu负载内存那些,如果一台机器有多张监控图形的话那需要使用selenium再具体定位了),将流量图下载到本地临时目录,之后拼接成一张。
主要遇到几个问题:
1. 使用selenium打开的cacti是无法直接用requests抓取的,直接使用requests抓取对应的src链接下载下来的会是html内容,也就是cacti的登录界面,所以使用selenium登录cacti后需要获取cookies,之后使用该cookies进行爬取。
2. 使用了PIL库,这个库在python3需要下载Pillow库,但是导入的时候需要使用PIL。
3. 不是问题的小问题,如果要使用pyinstaller打包成EXE,不要使用最新的(目前是2021.10)的python3.10,打包的时候会报错缺少模块,如果忽略该模块打包出来的EXE程序也无法使用会闪退,python3.6和3.8没有这个问题,不知道3.9行不行。昨晚把自己电脑的python3.8给换成3.10发现的这个问题,今晚回去改成3.9再试试。
cacti.py
# -*- coding: utf-8 -*-
# @Time : 2021/10/11 21:21
# @Author : TanDaBao
# @File : cacti.py
from time import sleep
from requests import get
from selenium import webdriver
from selenium.webdriver.support.ui import Select
import os
from PIL import Image # pip install Pillow
import datetime
#driver = webdriver.Chrome(r"C:Program Files (x86)GoogleChromeApplicationchromedriver.exe")
driver = webdriver.Chrome(r"C:Program FilesGoogleChromeApplicationchromedriver.exe")
driver.implicitly_wait(5)
driver.get("http://ip:端口/") # cacti访问链接
user = 'admin' # 账户
passwd = 'xxxxxxxxx' # 密码
# 在桌面创建目录用于临时存储cacti图片
path = os.path.join(os.path.expanduser("~"), 'Desktop')
#path = 'G:\桌面'
path_dir = path + '\test_Temporary_picture'
if not os.path.isdir(path_dir):
os.mkdir(path_dir)
# 登录、查看图像
def login():
zhanghu = driver.find_element_by_css_selector('[name="login_username"]')
mima = driver.find_element_by_css_selector('[name="login_password"]')
zhanghu.send_keys(user)
mima.send_keys(passwd)
driver.find_element_by_css_selector('[value="登录"]').click()
driver.find_element_by_css_selector('[alt="Graphs"]').click()
# 依次选择流量图并下载
def choice(quantity:int): # 传入图形数量
# 我需要的是第2个图形树,所以下标是1
driver.find_elements_by_xpath('//li/i')[1].click()
# 获取当前cookies
c = driver.get_cookies()
#print('get_cookies:', c)
cookies = {}
# 获取cookie中的name和value,转化成requests可以使用的形式
for cookie in c:
cookies[cookie['name']] = cookie['value']
#print('cookies:', cookies)
for i in range(quantity):
driver.find_elements_by_css_selector(
'[]')[i].click()
select_time = Select(driver.find_element_by_css_selector('[id="predefined_timespan"]'))
select_time.select_by_visible_text('昨天')
sleep(1)
# 定位流量图url并保存
src = driver.find_element_by_xpath('//div/a/img').get_attribute('src')
#print(src)
# 下载图片
proxies = {"http": None, "https": None}
img_url = get(src, cookies=cookies, proxies=proxies)
img_name = path_dir + '\' + str(i) + '.png'
with open(img_name, 'wb') as f:
f.write(img_url.content)
# 拼接流量图
def integration():
os.chdir(path_dir)
ims = [Image.open(path_dir + '\' + i) for i in os.listdir(path_dir) if i.endswith(".png")] # 打开路径下的所有图片
width, height = ims[0].size # 获取拼接图片的宽和高
result = Image.new(ims[0].mode, (width, height * len(ims)))
for j, im in enumerate(ims):
result.paste(im, box=(0, j * height))
# 格式化输出昨天日期
today = datetime.date.today()
oneday = datetime.timedelta(days=1)
yesterday = today - oneday
result.save(path + '\' + '%s带宽图.png' % yesterday)
# 删除临时目录及流量图
def clear():
os.chdir(path_dir)
path_list = os.listdir(path_dir)
for i in path_list:
os.remove(i)
os.chdir(path)
os.rmdir(path_dir)
if __name__ == "__main__":
login()
choice(9)
integration()
clear()
driver.quit()
执行过程会在桌面生成临时目录存储我要抓取的9张流量图,最后拼接完成后删除该目录。



