时间:2023-07-06 00:09:01 | 来源:网站运营
时间:2023-07-06 00:09:01 来源:网站运营
用python编写控制网络设备的自动化脚本8:网页:项目地址:pip install selenium
第二步,下载浏览器驱动,selenium要调用浏览器驱动才能使用。我比较喜欢用火狐,火狐浏览器驱动可以从GitHub下载(https://github.com/mozilla/geckodriver/releases),下载下来的压缩包解压后得到geckodriver.exe,随便扔到一个%PATH%目录中(C:/Program Files/Python38/Scripts)。import timeimport selenium.webdriver #seleniumv浏览器 = selenium.webdriver.Firefox()v浏览器.get("http://192.168.1.1")time.sleep(1)w密码 = v浏览器.find_element_by_id("lgPwd")w密码.send_keys("********")time.sleep(1)w确定 = v浏览器.find_element_by_id("loginSub")w确定.click()time.sleep(1)
运行结果如图:import selenium.webdriverdef f创建连接(a地址): v浏览器 = selenium.webdriver.Firefox() v浏览器.get(a地址) return v浏览器
f创建连接 的功能是创建一个浏览器对象,并打开具体地址。这段代码只是一个简单例子,实际的 f创建连接 要处理不同浏览器的情况,代码更复杂。from ..基础接口 import 设备from selenium.common import exceptions #seleniumclass I设备(设备.I设备): def __init__(self, a连接): self.m连接 = a连接 def fs地址(self, a地址): self.m连接.get(a地址) def fg地址(self): return self.m连接.current_url def f查找(self, a找: str): try: v元素 = self.m连接.find_element_by_xpath(a找) return 元素.C元素(v元素) except exceptions.NoSuchElementException as e: return None
网络设备脚本/网页接口/元素.pyclass C元素: """对selenium网页元素的封装""" def __init__(self, a元素): self.m元素 = a元素 def f查找(self, a找): return C元素(self.m元素.find_element_by_xpath(a找)) def f点击(self): self.m元素.click() def f清除(self): self.m元素.clear() def f输入(self, a): self.m元素.send_keys(a) def fg文本(self): if self.m元素.tag_name in ("input",): #表单控件从值属性取文本 return self.m元素.get_attribute("value") return self.m元素.text def fg属性(self, a属性名): return self.m元素.get_attribute(a属性名)
import cflw代码库py.cflw网页连接 as 网页连接import 网络设备脚本.普联 as 普联v连接 = 网页连接.f创建连接("http://192.168.1.1")v设备 = 普联.f创建设备(v连接, 普联.E型号.wdr5620)
这里说一下如何判断一个连接是否是网页连接。一般python中判断一个类型是否和另外一个类型相同或存在继承关系可以用type(a) == A
或isinstance(a, A)
这样的方法。selenium里面浏览器类都继承自selenium.webdriver.remote.webdriver.WebDriver
,写出来就变成isinstance(连接, selenium.webdriver.remote.webdriver.WebDriver)
,并且要在文件顶部写一句import selenium
,代码如下:import selenium.webdriver.remote.webdriverdef fi网页连接(a连接): return isinstance(a连接, selenium.webdriver.remote.webdriver.WebDriver)#好像没什么问题
这段判断代码看起来好像没什么问题,如果传进去的是其他连接就返回False,看起来很合理。但是忽略了一种重要情况,用户没有安装selenium的话,第一行会抛出ModuleNotFoundError异常。所以这时候就要寻找一种不导入模块也能判断网页连接的办法。a连接.__class__
会得到像 <class 'selenium.webdriver.firefox.webdriver.WebDriver'>
这样的一个类,只要揪着这个类名做判断就行。def fi网页(a连接): if "selenium" in str(a连接.__class__): #selenium return True return False
至于判断型号判断版本没什么好说的,用一堆if...elif...else就行了。f创建设备
长得像这样:from .基础接口 import 连接层def f创建设备(a连接, a型号, a版本 = 0): if 连接层.fi网页(a连接): from .普联网页 import 设备 return 设备.C设备(a连接, a型号, a版本) raise ValueError("不支持的连接")
其中的C设备
就是具体的设备类,其构造函数接收连接、型号、版本,供模式层使用。from ..网页接口 import 设备class C设备(设备.I设备): def __init__(self, a连接, a型号, a版本): 设备.I设备.__init__(self, a连接) self.m型号 = a型号 self.m版本 = a版本
f创建设备
得到设备对象后,接着获取一个用户模式,用户模式是网络设备正常运行情况下通往其他模式的入口,既然是入口,也就包含了登录操作。在脚本中,这个过程就像这样:import cflw代码库py.cflw网页连接 as 网页连接import 网络设备脚本.普联 as 普联v连接 = 网页连接.f创建连接("http://192.168.0.1")v设备 = 普联.f创建设备(v连接, 普联.E型号.wdr5620)v用户模式 = v设备.f模式_用户()v用户模式.f登录(a密码 = "******")
f模式_用户
的内容很简单,直接创建一个用户模式对象并返回。from ..网页接口 import 设备class C设备(设备.I设备): def f模式_用户(self): from . import 用户模式 return 用户模式.C用户模式(self)
接着是用户模式。在网页中,一个网页模式总是保存设备对象,以实现对网页的操控。所以这个C用户模式
有2个函数,一个构造函数,一个登录函数。import timefrom ..基础接口 import 用户模式class C用户模式(用户模式.I用户模式): def __init__(self, a设备): self.m设备 = a设备 def f登录(self, a密码 = "", a用户名 = None): w密码框 = self.m设备.f查找("//input[@id='lgPwd']") w密码框.f输入(a密码) w确定 = self.m设备.f查找("//input[@id='loginSub']") w确定.f点击()
其中的f登录
就是把“获取网页元素和操控网页的过程”一节的代码拿过来改一改,就变成了封装过一遍的代码。f手动输入验证码
用来把焦点聚集在输入框中,让用户手动输入验证码,并且判断验证码是否输入完毕。import cflw代码库py.cflw时间 as 时间from . import 元素def f手动输入验证码(a元素, a长度): a元素.f聚焦() v循环阻塞 = 时间.C循环阻塞(60, a间隔 = 1) while v循环阻塞.f滴答(): if len(a元素.fg文本()) >= a长度: #有输入 return True else: #没有输入 return False
在f登录
中,先获取网页元素,自动输入用户名密码,接着手动输入验证码,最后判断是否登录成功。import timefrom ..基础接口 import 用户模式from ..基础接口 import 异常from ..网页接口 import 图片class C用户模式(用户模式.I用户模式): def f登录(self, a用户名, a密码): w用户名 = self.m设备.f查找("//*[@id=/"user/"]") w用户名.f输入(a用户名) w密码 = self.m设备.f查找("//*[@id=/"password/"]") w密码.f输入(a密码) w验证码 = self.m设备.f查找("//*[@id=/"verify/"]") w登录 = self.m设备.f查找("//*[@id=/"button/"]") v验证码 = 图片.f手动输入验证码(w验证码, 4) if v验证码: w登录.f点击() time.sleep(1) # 结束 self.m设备.f查找_直到('//*[@id="ext-gen100"]') time.sleep(1)
class C模式wdr5620: c网络状态 = ("netStateMbtn",) c设备管理 = ("routeMgtMbtn",) c设备管理_主人网络 = ("routeMgtMbtn", "linkedEpt_rsMenu") c设备管理_已禁设备 = ("routeMgtMbtn", "limitedEpt_rsMenu") c应用管理 = ("appsMgtMbtn",) c路由设置 = ("routerSetMbtn",) c路由设置_tplinkid = ("routerSetMbtn", "cloudAnt_rsMenu") c路由设置_上网设置 = ("routerSetMbtn", "network_rsMenu") c路由设置_无线设置 = ("routerSetMbtn", "wireless2G_rsMenu") c路由设置_lan口设置 = ("routerSetMbtn", "lanSet_rsMenu") c路由设置_dhcp服务器设置 = ("routerSetMbtn", "dhcpServer_rsMenu") c路由设置_修改管理员密码 = ("routerSetMbtn", "changeWebPwd_rsMenu") c路由设置_备份和载入配置 = ("routerSetMbtn", "bakRrestore_rsMenu") c路由设置_重启和恢复出厂 = ("routerSetMbtn", "reBootSet_rsMenu") c路由设置_系统日志 = ("routerSetMbtn", "sysLog_rsMenu")
然后在设备类中实现切换过程class C设备: def __init__(self, a连接, a型号, a版本): #省略其他代码 self.ma模式 = [] def f切换模式(self, aa模式: tuple): if self.ma模式 == aa模式: return for v模式 in aa模式: v元素 = self.f查找(f"//*[@id='{v模式}']") v元素.f点击() self.ma模式 == aa模式
其实这里还可以优化一下,从最顶级开始逐级判断是否不同模式,然后从那个不同的地方开始切换,这样可以减少点击次数,加快切换模式的速度。我懒得优化了,反正python很慢,网络也很慢,所以慢就慢了。import selenium.webdriver #seleniumfrom ..网页接口 import 设备 as 网页设备from ..命令行接口 import 命令from ..命令行接口 import 设备 as 命令行设备from ..思科命令行.常量 import *from . import 命令行用户模式 as 实现用户模式class C设备(网页设备.I设备, 命令行设备.I设备): """适用于: c7200""" def __init__(self, a连接, a型号, a版本): 网页设备.I设备.__init__(self, a连接) 命令行设备.I设备.__init__(self, a连接) self.m型号 = a型号 self.m版本 = a版本 self.ma模式栈 = [] #网页 def fg命令框(self, a包装 = True): w命令框 = self.f查找("/html/body/pre/form/dt/input[2]", a包装) return w命令框 #适配 def f输出(self): w输出框 = self.f查找("/html/body/pre/form/dt/pre", False) return w输出框.text def f输入(self, a文本): w命令框 = self.fg命令框(False) w命令框.send_keys(str(a文本)) def f刷新(self): w命令框 = self.fg命令框(False) w命令框.clear() w命令框.send_keys(selenium.webdriver.common.keys.Keys.ENTER) #模式 def f模式_用户(self): return 实现用户模式.C用户模式(self) #命令 def f退出(self): self.f执行命令("exit") def f执行命令(self, a命令): w命令框 = self.fg命令框(False) w命令框.send_keys(str(a命令)) w命令框.send_keys(selenium.webdriver.common.keys.Keys.ENTER) time.sleep(0.5) return self.f输出()
这里有一部分模式类也要重写,比如用户模式,思科c7200的登录过程在打开网页的过程中弹出的登录框中输入用户名密码登录。这个登录框由浏览器控制,不属于网页元素。所以用户模式的 f登录 要省略掉。import timefrom ..思科命令行 import 用户模式class C用户模式(用户模式.C用户模式): def __init__(self, a): 用户模式.C用户模式.__init__(self, a) def f登录(self): time.sleep(0.5) self.m设备.f输入_结束符() def f模式_全局配置(self): from . import 命令行全局配置 return 命令行全局配置.C全局配置(self)
要重写的还有全局配置模式,思科网页中进入全局配置模式的命令是“configure http”,和命令行不一样,所以进入模式命令也得改:from ..思科命令行 import 全局配置class C全局配置(全局配置.C全局配置): def __init__(self, a): 全局配置.C全局配置.__init__(self, a) def fg进入命令(self): return "configure http"
ip http serverusername asdf privilege 15 password 123456interface fastethernet 0/0 ip address dhcpline vty 0 4 login local
检查路由器获取到的地址,然后确认电脑是否能访问路由器。import cflw代码库py.cflw网页连接 as 网页连接import 网络设备脚本 as 脚本import 网络设备脚本.思科 as 思科def main(): v连接 = 网页连接.f创建连接("http://asdf:123456@192.168.44.129") v设备 = 思科.f创建设备(v连接, 思科.E型号.c7200, 15.2) #用户 v用户模式 = v设备.f模式_用户() v用户模式.f登录() #全局配置 v全局配置 = v用户模式.f模式_全局配置() #接口配置l0 v接口配置 = v全局配置.f模式_接口("l0") v接口配置.fs网络地址4("1.1.1.1/32") #接口配置f0/0 v接口配置 = v全局配置.f模式_接口("f0/1") v接口配置.fs网络地址4("12.0.0.1/24") #用户配置 v用户配置 = v全局配置.f模式_用户("asdf") v用户配置.fs密码("123456")if __name__ == "__main__": main()
运行结果:关键词:自动化,脚本,设备,编写,控制,网络