我们可以 使用python通过ssh或者api操作网络设备,但是有时候需要web操作,可以使用selenium来实现自动化操作

selenium介绍

selenium 是一个web的自动化测试工具,不少学习功能自动化的同学开始首选selenium ,相因为它相比QTP有诸多有点:

  • 免费,也不用再为破解QTP而大伤脑筋

  • 小巧,对于不同的语言它只是一个包而已,而QTP需要下载安装1个多G 的程序。

  • 这也是最重要的一点,不管你以前更熟悉C、 java、ruby、python、或都是C# ,你都可以通过selenium完成自动化测试,而QTP只支持VBS

  • 支持多平台:windows、linux、MAC ,支持多浏览器:ie、ff、safari、opera、chrome

  • 支持分布式测试用例的执行,可以把测试用例分布到不同的测试机器的执行,相当于分发机的功能。

可以直接通过pip安装selenium

pip install selenium

selenium ide

Selenium IDE实现为Firefox扩展,在测试脚本上提供记录和回放功能。 它允许测试人员以HTML,Java,Ruby,RSpec,Python, C# ,JUnit和TestNG等多种语言导出录制的脚本。 可以在Selenium RC或Webdriver中使用这些导出的脚本。 在使用selenium ide后,我们就不需要对html和web前端的便签进行定位操作,简化selenium使用,降低门槛,我们只要吧ide中记录的操作顺序使用脚本写入即可。 selenium同时支持chrome浏览器,下载和使用详细间官网文档

https://www.selenium.dev/selenium-ide/docs/en/introduction/getting-started

完成selnenium ide的chrome插件安装后,如下所示

image.png

使用效果如下: image.png

只要记录对应的步骤即可,以下是打开一个baidu搜索的例子 image.png

image.png

image.png

以下就是对应元素的操作记录 image.png

webdrive

Selenium WebDriver是Selenium Tool套件中最重要的组件。 最新版本“Selenium 2.0”与WebDriver API集成,提供更简单,更简洁的编程接口。

在WebDriver中,可以使用任何支持的编程语言开发测试脚本,并且可以在大多数现代Web浏览器中直接运行。WebDriver支持的语言包括C#,Java,Perl,PHP,Python和Ruby

image.png

根据自己的浏览器下载对应的webdrive,我用的是chrome https://chromedriver.chromium.org/downloads

image.png

selnium简单使用

安装selenium

pip install selenium

测试

创建baidu.py,输入以下内容

from selenium import webdriver


driver = webdriver.Chrome()
driver.get('https://www.baidu.com')

print(driver.title)

driver.quit()

如果执行报错,需要安装对应驱动

selenium3 浏览器驱动

当selenium升级到3.0之后,对不同的浏览器驱动进行了规范。如果想使用selenium驱动不同的浏览器,必须单独下载并设置不同的浏览器驱动。

Firefox浏览器驱动:geckodriver

Chrome浏览器驱动:chromedriver , taobao备用地址

IE浏览器驱动:IEDriverServer

Edge浏览器驱动:MicrosoftWebDriver

Opera浏览器驱动:operadriver

PhantomJS浏览器驱动:phantomjs

选择的时候注意要选择与自己的浏览器匹配的版本下载

将下载的文件解压,放在如下位置

unzip chromedriver_linux64.zip

/usr/bin/chromedriver

给予执行权限

chmod +x /usr/bin/chromedriver

selenium 元素定位

提供了8种定位方式

  • id
  • name
  • class name
  • tag name
  • link text
  • partial link text
  • xpath
  • css celector

这8种定位方式在selenium中的对应的方位为

  • find_element_by_id()
  • find_element_by_name()
  • find_element_by_class_name()
  • find_element_by_tag_name()
  • find_element_by_link_text()
  • find_element_by_partial_link_text()
  • find_element_by_xpath()
  • find_element_by_css_selector()

定位方法的用法

假如我们有一个Web页面,通过前端工具(如,Firebug)查看到一个元素的属性是这样的。

<html>
  <head>
  <body link="#0000cc">
    <a rel="nofollow" id="result_logo" href="/" onmousedown="return c({'fm':'tab','tab':'logo'})">
    <form id="form" class="fm" name="f" action="/s">
      <span class="soutu-btn"></span>
        <input id="kw" class="s_ipt" name="wd" value="" maxlength="255" autocomplete="off">

目的是要定位input标签的输入框

  • 通过id定位:
dr.find_element_by_id("kw")
  • 通过name定位
df.find_element_by_name("wd")
  • 通过class name定位
dr.find_element_by_class_name("s_ipt")
  • 通过tag name定位
df.find_element_by_tag_name("input")
  • 通过xpath定位,以下是几种常用写法:
dr.find_element_by_xpath("//*[@id='kw']")
dr.find_element_by_xpath("//*[@name='wd']")
dr.find_element_by_xpath("//input[@class='s_ipt']")
dr.find_element_by_xpath("/html/body/form/span/input")
dr.find_element_by_xpath("//span[@class='soutu-btn']/input")
dr.find_element_by_xpath("//form[@id='form']/span/input")
dr.find_element_by_xpath("//input[@id='kw' and @name='wd']")
  • 通过css定位,css定位有N种写法,以下为几个常用写法:
dr.find_element_by_css_selector("#kw")
dr.find_element_by_css_selector("[name=wd]")
dr.find_element_by_css_selector(".s_ipt")
dr.find_element_by_css_selector("html > body > form > span > input")
dr.find_element_by_css_selector("span.soutu-btn> input#kw")
dr.find_element_by_css_selector("form#form > span > input")

例如如下的页面有一组文本链接

<a rel="nofollow" class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>
<a rel="nofollow" class="mnav" href="http://www.hao123.com" name="tj_trhao123">hao123</a>
  • 通过link text定位
dr.find_element_by_link_text("新闻")
dr.find_element_by_link_text("hao123")
dr.find_element_by_partial_link_text("新")
dr.find_element_by_partial_link_text("hao")
dr.find_element_by_partial_link_text("123")

控制浏览器操作

控制浏览器的窗口大小

有时候我们希望能以某种浏览器尺寸打开,让访问的页面在这种尺寸下运行,例如可以将刘浏览器的设置为移动端的大小,(400*800),然后访问移动站点,对其样式进行评估

WebDrive提供了set_windows_size()方法来设置浏览器的大小

from selenium import webdriver

driver = webdriver.Firefox()
driver.get("http://m.baidu.com")

# 参数数字为像素点
print("设置浏览器宽480、高800显示")
driver.set_window_size(480, 800)
driver.quit()

在PC端执行自动化测试脚本大多情况下是希望浏览器在全屏的模式下执行,那么可以使用maximize_window()方法使打开的浏览器全屏显示,用法跟set_window_size()相同,但是他 不需要参数

控制浏览器后退,前进

在使用留恋起浏览网页的时候,浏览器提供了后退和前进按钮,可以方便的在浏览过的网页之间切换,WebDriver也提供了对应的back()和forward()方法来模拟后退和前进按钮,

from selenium import webdriver

driver = webdriver.Firefox()

#访问百度首页
first_url= 'http://www.baidu.com'
print("now access %s" %(first_url))
driver.get(first_url)

#访问新闻页面
second_url='http://news.baidu.com'
print("now access %s" %(second_url))
driver.get(second_url)

#返回(后退)到百度首页
print("back to  %s "%(first_url))
driver.back()

#前进到新闻页
print("forward to  %s"%(second_url))
driver.forward()

driver.quit()

刷新页面

手动刷新(F5)页面

driver.refresh() #刷新当前页面

WebDriver常用方法

点击和输入

定位元素只是第一步,定位之后需要对这个元素进行操作,或淡季(按钮)或者输入(输入框),以下为几种常用用法

  • clear() : 清除文本
  • send_keys(value): 模拟按键输入
  • click():单击元素
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

driver.find_element_by_id("kw").clear()
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()

driver.quit()

提交

  • submit()

submit()方法用于提交表单,例如在搜索输入关键字之后的回车操作,就可以通过该方法模拟

from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

search_text = driver.find_element_by_id('kw')
search_text.send_keys('selenium')
search_text.submit()

driver.quit()

有时候 submit()可以与 click()方法互换来使用, submit()同样可以提交一个按钮, 但 submit()的应用范围远不及 click()广泛。

其他常用方法

  • size:返回元素尺寸
  • text:获取元素的文本
  • get_attribute(name) :获得属性值
  • is_displayed():设置元素是否用户可见
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("http://www.baidu.com")

# 获得输入框的尺寸
size = driver.find_element_by_id('kw').size
print(size)

# 返回百度页面底部备案信息
text = driver.find_element_by_id("cp").text
print(text)

# 返回元素的属性值, 可以是 id、 name、 type 或其他任意属性
attribute = driver.find_element_by_id("kw").get_attribute('type')
print(attribute)

# 返回元素的结果是否可见, 返回结果为 True 或 False
result = driver.find_element_by_id("kw").is_displayed()
print(result)

driver.quit()

输出结果

{'width': 500, 'height': 22}
©2015 Baidu 使用百度前必读 意见反馈 京 ICP 证 030173 号
text
True

执行上面的程序并查看结果: size 方法用于获取百度输入框的宽、 高, text 方法用于获得百度底部的备案信息, get_attribute()用于获得百度输入的 type 属性的值, is_displayed()用于返回一个元素是否可见, 如果可见则返回 True, 否则返回 False。

鼠标事件

在 WebDriver 中, 将这些关于鼠标操作的方法封装在 ActionChains 类提供。

ActionChains 类提供了鼠标操作的常用方法:

  • perform(): 执行所有 ActionChains 中存储的行为;

  • context_click(): 右击;

  • double_click(): 双击;

  • drag_and_drop(): 拖动;

  • move_to_element(): 鼠标悬停。

鼠标悬停操作

from selenium import webdriver
# 引入 ActionChains 类
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Chrome()
driver.get("https://www.baidu.cn")

# 定位到要悬停的元素
above = driver.find_element_by_link_text("设置")
# 对定位到的元素执行鼠标悬停操作
ActionChains(driver).move_to_element(above).perform()

……

from selenium.webdriver import ActionChains 导入提供鼠标操作的 ActionChains 类。

ActionChains(driver) 调用 ActionChains()类, 将浏览器驱动 driver 作为参数传入。

move_to_element(above) context_click()方法用于模拟鼠标右键操作, 在调用时需要指定元素定位。

perform() 执行所有 ActionChains 中存储的行为, 可以理解成是对整个操作的提交动作。

键盘事件

Keys()类提供了键盘上几乎所有按键的方法。 前面了解到, send_keys()方法可以用来模拟键盘输入, 除此 之外, 我们还可以用它来输入键盘上的按键, 甚至是组合键, 如 Ctrl+A、 Ctrl+C 等。

from selenium import webdriver
# 引入 Keys 模块
from selenium.webdriver.common.keys import Keys

driver = webdriver.Chrome()
driver.get("http://www.baidu.com")

# 输入框输入内容
driver.find_element_by_id("kw").send_keys("seleniumm")

# 删除多输入的一个 m
driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)


# 输入空格键+“教程”
driver.find_element_by_id("kw").send_keys(Keys.SPACE)
driver.find_element_by_id("kw").send_keys("教程")

# ctrl+a 全选输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'a')

# ctrl+x 剪切输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x')

# ctrl+v 粘贴内容到输入框
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'v')

# 通过回车键来代替单击操作
driver.find_element_by_id("su").send_keys(Keys.ENTER)
driver.quit()
  • from selenium.webdriver.common.keys import Keys

在使用键盘按键方法前需要先导入 keys 类。

以下为常用的键盘操作:

send_keys(Keys.BACK_SPACE) 删除键(BackSpace)

send_keys(Keys.SPACE) 空格键(Space)

send_keys(Keys.TAB) 制表键(Tab)

send_keys(Keys.ESCAPE) 回退键(Esc)

send_keys(Keys.ENTER) 回车键(Enter)

send_keys(Keys.CONTROL,'a') 全选(Ctrl+A)

send_keys(Keys.CONTROL,'c') 复制(Ctrl+C)

send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X)

send_keys(Keys.CONTROL,'v') 粘贴(Ctrl+V)

send_keys(Keys.F1) 键盘 F1

……

send_keys(Keys.F12) 键盘 F12

获取断言信息

不管是在做功能测试还是自动化测试,最后一步需要拿实际结果与预期进行比较。这个比较的称之为断言。

我们通常可以通过获取title 、URL和text等信息进行断言。text方法在前面已经讲过,它用于获取标签对之间的文本信息。 下面同样以百度为例,介绍如何获取这些信息。

from selenium import webdriver
from time import sleep


driver = webdriver.Firefox()
driver.get("https://www.baidu.com")

print('Before search================')

# 打印当前页面title
title = driver.title
print(title)

# 打印当前页面URL
now_url = driver.current_url
print(now_url)

driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
sleep(1)

print('After search================')

# 再次打印当前页面title
title = driver.title
print(title)

# 打印当前页面URL
now_url = driver.current_url
print(now_url)

# 获取结果数目
user = driver.find_element_by_class_name('nums').text
print(user)

driver.quit()

使用selnium登录路由器并操作

这里简单模拟登录家用路由器,修改首先通过selnium ide获取登录步骤和关键命令,然后使用脚本自动化操作 image.png

相关脚本如下:

#使用selenuim模块测试登陆网络设备
from selenium import webdriver
import time
import os
import logging #记录日志模块

class Login_web(object):
    def __init__(self,logger):
        self.logger=logger
        self.logger.info("-----start log----------")
        self.browser=webdriver.Chrome()
        self.logger.info("start browser successfuly")

        self.url='http://192.168.3.1/html/index.html#/login' #需要登录的url
        #self.username='admin'
        self.password='WAN15807189615'

    def login(self):
        self.browser.get(self.url)
        self.browser.implicitly_wait(5)
        self.browser.find_element_by_id('userpassword_ctrl').send_keys(self.password)
       # self.browser.find_element_by_id('pwd').send_keys(self.password)
        #self.browser.find_element_by_id('submit').click()
        self.browser.find_element_by_id('loginbtn').click()
        self.browser.execute_script('window.scrollTo(0,0)')
        #self.browser.find_element_by_class_name('.big_icon.want_more_press').click()
        self.browser.find_element_by_xpath('//li[5]/div').click() ## css建议通过xpath查找元素
        self.browser.implicitly_wait(5)
        self.logger.info('logging ok!!!')

    def operation(self):
        self.browser.find_element_by_id('systemsettingsparent_menuId').click()
        self.browser.find_element_by_id('applicationparent_menuId').click()
        self.browser.find_element_by_id('domainlist_open_on').click()
        self.browser.find_element_by_id('domainlist_open_off').click()
        self.browser.find_element_by_id('logout_btn').click()
        self.logger.info('operation ok!!!')



    def close(self):
        return self.browser.close()

class Log():
    def __init__(self,filename):
        self.filename=filename

    def creatdir(self):
        DIR=os.path.join(os.path.dirname(__file__),'log')
        TIME=time.strftime('%Y-%m-%d',time.gmtime())+'-'
        LOGNAME=TIME+self.filename
        LOGFILENAME=os.path.join(DIR,LOGNAME)
        if not os.path.exists(DIR):
            os.mkdir(DIR)
        return LOGFILENAME

    def createlogger(self,logfilename):
        logger = logging.getLogger()
        logger.setLevel(logging.INFO)
        handler = logging.FileHandler(logfilename)
        handler.setLevel(logging.INFO)
        formater = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        handler.setFormatter(formater)
        logger.addHandler(handler)
        return logger

if __name__=='__main__':
    loger=Log('text.log')
    logfilename=loger.creatdir()
    logger=loger.createlogger(logfilename)
    login_web=Login_web(logger)
    login_web.login()
    login_web.operation()
    time.sleep(3)
    login_web.close()

总结

1.selenium ide简化元素标签查找,同时也能直接通过回放方式操作网页 2.有些html元素如果使用id查不到的化,可以使用xpath方式 3.webdrive的版本一定要跟自己的浏览器对应 4.有必要学学web前端,至少要了解点基础

哈哈哈,以后如果要批量web操作网络设备,但是设备又不能提供ssh,api,比如华为话机的操作,就可以用这种方式。

感觉运维工作又轻松了