目的是截图,截昨天的几台服务器的流量图,不是取数据写入文件。
步骤:selenium打开cacti网站并登录,点击选择到对应的图形树,遍历点击设备图形id,将流量图下载到本地临时目录,之后拼接成一张。
主要遇到几个问题:
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)\Google\Chrome\Application\chromedriver.exe")
driver = webdriver.Chrome(r"C:\Program Files\Google\Chrome\Application\chromedriver.exe")
driver.implicitly_wait(5)
driver.get("http://ip:port/")
user = 'admin'
passwd = 'password'
# 在桌面创建目录用于临时存储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(): # 传入图形数量
# 107416是第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']
# 机器图形ID定位
id_list = ["node26_1087_anchor","node26_1090_anchor","node26_1092_anchor","node26_1096_anchor",
"node26_1100_anchor","node26_1102_anchor","node26_1105_anchor","node26_1116_anchor",
"node26_1117_anchor","node26_1118_anchor","node26_1120_anchor"]
# 先随便点个设备的流量图,选择昨天
driver.find_element_by_id(id_list[0]).click()
select_time = Select(driver.find_element_by_css_selector('[id="predefined_timespan"]'))
select_time.select_by_visible_text('昨天')
for id in id_list:
driver.find_element_by_id(id).click()
sleep(2)
# 定位流量图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 + '\\' + id + '.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()
integration()
clear()
driver.quit()
执行过程会在桌面生成临时目录存储我要抓取的9张流量图,最后拼接完成后删除该目录。