美文网首页
web自动化-selenium(一)

web自动化-selenium(一)

作者: 在下YM | 来源:发表于2022-02-08 21:26 被阅读0次
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    option,select{
        width: 100px;
    }
    option{
        height: 20px;
    }
</style>

<body>
    <form action="" method="get">
        <input type="text" id="username" name="username" placeholder="username" class='input-text'>
        <br />
        <input type="password" id="password" name="password" placeholder="password" class="input-password">
        <br />
        <input type="text" name="password2" placeholder="确认密码"><br />
    </form>
    <H8>&nbsp;</H8>
    <div id='links'>
        <ul>
            <li><a>标签</a></li>
            <li><a>Genetic Algorithms in Search, Optimization, and Machine Learning</a></li>
            <li>hello</li>
            <li>world</li>
        </ul>
    </div>
    <H8>&nbsp;</H8>
    <div>
        <button id="button" onclick="click()">我是一个按钮</button>
        <span id="click_count">鼠标单击次数: 0</span>
    </div>
    <H8>&nbsp;</H8>
    <div>
        <select name="select" id="select-single">
            <option value="1" selected>zhangsan</option>
            <option value="2">lisi</option>
            <option value="3">wangwu</option>
            <option value="4">zhaoliu</option>
            <option value="5">tangli</option>
        </select>
    </div>
    <H8>&nbsp;</H8>
    <div>
        <select name="select" id="select-multiple" multiple>
            <option value="1" selected>zhangsan</option>
            <option value="2">lisi</option>
            <option value="3">wangwu</option>
            <option value="4">zhaoliu</option>
            <option value="5">tangli</option>
        </select>
    </div>
</body>
<script>

    let click_count = 0
    let button = document.getElementById('button')
    button.onclick = function click(event) {
        click_count++;
        document.getElementById('click_count').innerHTML = `鼠标单击次数: ${click_count}`;
    }
</script>

</html>

什么是Selenium

  • Selenium是一个用于Web应用程序测试的工具,可以直接调用浏览器,它支持所有主流的浏览器。

  • 最初是为网站自动化测试而开发的,但却被很多爬虫爱好者发扬光大

  • 官网:https://www.selenium.dev/

Selenium特点

  • 开源软件:源代码开放可以根据需要来增加工具的某些功能
  • 跨平台:linux 、windows 、mac
  • 核心功能:就是可以在多个浏览器上进行自动化测试
  • 多语言:Java、Python、C#、JavaScript、Ruby等
  • 成熟稳定:目前已经被google , 百度, 腾讯等公司广泛使用
  • 功能强大:能够实现类似商业工具的大部分功能,因为开源性,可实现定制化功能

什么是WebDriver?

Webdriver 是一种用于控制浏览器的程序,不同的浏览器有不同的 webdriver。

  • Chrome (ChromeDriver)

  • IE(InternetExplorerDriver)

  • Opera(OperaDriver)

  • Firefox (FirefoxDriver)

  • safari(SafariDriver)

  • HtmlUnit (HtmlUnit Driver)
    webdriver 提供了对外的接口,其他程序通过这些接口控制 webdriver 与浏览器的交互。例如:我们可以写 python 程序来调用 webdriver 的接口。实际上从其他程序的角度看,webdriver 就是充当了和浏览器交互的一个桥梁。

  • 提示:
    Firefox、Chrome:对元素定位和操作有良好的支持,同时对JavaScript支持也非常好。
    IE: 只能在windows平台运行,所有浏览器中运行速度最慢
    HtmlUnit:无GUI(界面)运行,运行速度最快;

Selenium 执行过程

python代码--> selenium 封装的 python 接口--> WebDriver 提供接口--> 浏览器

环境搭建

基于Python环境搭建

pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple

注意: 在安装selenium时,前提是Python3.5以上版本安装完毕且能正常运行

谷歌浏览器驱动安装

确认浏览器的版本


查看方式

下载驱动

下载与浏览器版本一致的驱动版本

谷歌浏览器驱动下载地址

国内不能直接访问Chrome官网,可以在ChromeDriver仓库中下载 或者 https://npm.taobao.org/mirrors/chromedriver

选择自己对应的平台版本

WebDriver 元素定位简单方式

selenium页面元素定位的方法,是在selenium中可以通过多种方式来定位标签,返回标签元素对象:

  • 通过 id 属性定位 : find_element_by_id
  • 通过 name 属性定位 : find_element_by_name
  • 通过 class 属性定位 : find_element_by_class_name
  • 通过标签名定位 : find_element_by_tag_name
  • 通过内容定位 a 标签(绝对匹配) : find_element_by_link_text
  • 通过内容定位 a 标签(模糊匹配) : find_element_by_partial_link_text
from selenium.webdriver import Chrome
import traceback
from selenium.webdriver.chrome.service import *

from selenium.webdriver.common.by import By

service = Service("./chromedriver")
driver = Chrome(service=service)
# 通过指定chromedriver的路径来实例化driver对象

# 控制浏览器访问url地址
# file://{本地文件绝对路径}
driver.get('file://./test.html')  # 打开本地 html 文件

try:
    print(driver.find_element_by_id('username')) # 通过 id 属性定位
    driver.find_element_by_name('password2')  # 通过 name 属性定位
    driver.find_element_by_class_name('input-password') # 通过 class 属性定位
    driver.find_element_by_tag_name('ul') # 通过标签名定位
    driver.find_element_by_link_text('标签') # 通过内容定位 a 标签(绝对匹配)
    driver.find_element_by_partial_link_text('Optimization')  # 通过内容定位 a 标签(模糊匹配)
except Exception:
    print(traceback.format_exc())
finally:
    # 退出浏览器
    driver.quit()
  • Chrome(executable_path='./chromedriver')中executable参数指定的是下载好的chromedriver文件的路径
  • 要在代码中尽量保证driver.quit()能够成功执行,进而关闭driver退出模拟浏览器;不然将在操作系统中残留进程,对系统造成不必要的压力
  • find_element_by_方式已不推荐使用,推荐使用find_element(By_,元素)

xpath 方式

  1. XPath 即为 XML Path 的简称,它是一种用来确定 XML/HTML 文档中某部分位置的语言。
  2. XPath文档:http://www.w3school.com.cn/xpath/index.asp
  3. HTML 可以看做是 XML 的一种实现,所以 Selenium 用户可以使用这种强大的语言在Web应用中定位元素。

xpath路径

  • html,xml 中的元素可以嵌套其他元素,但是根元素只有一个。我们可以这种嵌套关系看成路径。路径分绝对路径和相对路径:
  • 绝对路径:从根元素到指定元素之间所有经过元素层级路径,绝对路径以 "/" 开始,例如: input 的绝对路径是: /html/body/form/input
  • 相对路径:从任何元素开始到该元素的路径,相对路径以 "//" 开始,例如: 用户名输入框标签的相对路径有: //form/input,//body/form/input

xpath 定位

xpath 定位是结合路径来进行定位的,分为绝对定位和相对定位。定位过程中还可以结合元素的属性值。

定位方法是 find_element_by_xpath

纯路径定位

绝对定位: find_element_by_xpath("/html/body/form/input")

相对定位: find_element_by_xpath("//div/ul/li/a")

结合属性

单个属性: find_element_by_xpath("//input[@type='text']")

多个属性: driver.find_element_by_xpath("//input[@type='text' and @name='username']")

选择上一级元素

find_element_by_xpath("//input/..") 返回的是 form 元素

满足条件的多个元素,选择其中一个

driver.find_element_by_xpath("//ul/li") 有多个 li 满足条件,选择其中一个,通过下标来完成,下标从 1 开始

driver.find_element_by_xpath("//ul/li[1]")

可以结合特殊方法 last() 从后面开始选择 ,比如 //ul/li[last()] 选择最后一个 //ul/li[last()-1] 倒数第二个

from selenium.webdriver import Chrome
import traceback

# 通过指定chromedriver的路径来实例化driver对象
driver = Chrome(executable_path='./chromedriver')

# 控制浏览器访问url地址
# file://{本地文件绝对路径}
driver.get('file:///home/python/code/unit_testing/selenium_code/test.html')  # 打开本地 html 文件

try:
    print(driver.find_element_by_xpath('/html/body/form/input'))
    print(driver.find_element_by_xpath('//div/ul/li'))

    print(driver.find_element_by_xpath('//form/input[@name="password"]'))
    print(driver.find_element_by_xpath('//form/input[@name="password2" and @type="text"]'))

    print(driver.find_element_by_xpath('//li/..'))

    print(driver.find_element_by_xpath('//ul/li[1]'))
    print(driver.find_element_by_xpath('//ul/li[last()]'))
    print(driver.find_element_by_xpath('//ul/li[last()-1]'))
except Exception:
    print(traceback.format_exc())
finally:
    # 退出浏览器
    driver.quit()

CSS 方式

CSS 选择器

CSS 选择器参考手册

在Selenium中也可以使用这种选择器,通过 find_element_by_css_selector:

  1. 在selenium中极力推荐CSS定位,因为它比XPath定位速度要快
  2. CSS 选择器语法非常强大,在这里我们只学习在测试中常用的几个
选择器 例子 描述
#id #userA id选择器,选择id="userA"的所有元素
.class .telA class选择器,选择class="telA"的所有元素
element input 选择所有input元素
[attribute=value] [type="password"] 选择type="password"的所有元素
element>element p>input 选择所有父元素为p元素的input元素
driver.find_element_by_css_selector('#username') # 通过 id
driver.find_element_by_css_selector('.input-text') # 通过 class
driver.find_element_by_css_selector('form') # 通过标签名
driver.find_element_by_css_selector('input[type="password"]') # 通过标签属性
driver.find_element_by_css_selector('div>ul') # 通过父子元素

查询多个元素

  • 通过 id 属性定位 : find_elements_by_id
  • 通过 name 属性定位 : find_elements_by_name
  • 通过 class 属性定位 : find_elements_by_class_name
  • 通过标签名定位 : find_elements_by_tag_name
  • 通过内容定位 a 标签(绝对匹配) : find_elements_by_link_text
  • 通过内容定位 a 标签(模糊匹配) : find_elements_by_partial_link_text
  • 通过 xpath : find_elements_by_xpath
  • 通过 CSS 选择器: find_elements_by_css_selector
    和选择单个元素的字面区别就是多了个 s。
调用这类方法,会返回一个列表,没有找到元素则返回空列表,查找单个元素的方法会在找不到元素时抛出 NoSuchElementException 异常
driver.find_elements_by_id('#no-exist-id') # 返回空数组

driver.find_elements_by_tag_name('li') #  返回数组多个元素

什么是元素等待?

概念:WebDriver定位页面元素时如果未找到,会在指定时间内一直等待的过程。

为什么要设置元素等待?

当使用脚本定位元素或去验证程序的运行状态时,由于资源受限或网络延迟引起的响应速度太慢,导致要定位的元素还未加载到页面。

例如:页面是通过 Ajax 发起请求,但是网络有延迟,提交按钮点击完后,页面等待服务器的返回结果来更新页面,那么在这期间,测试代码是不能够直接去查找预期的元素的。

元素等待类型

显式等待
隐式等待

显式等待

概念:使 WebDriver 等待某个条件成立,否则在达到最大时长时抛出超时异常(TimeoutException)

WebDriverWait 类

from selenium.webdriver.support.wait import WebDriverWait

参数:

  • driver: webdriver对象
  • timeout: 等待多长时间
  • poll_frequency: 每次执行失败时休眠多长时间
调用方法

WebDriverWait.util(method, message=''):

参数说明:

  • method 函数,这个函数必须定义一个参数,接受 driver 对象。例如: def contain_title(driver)
  • message 如果等待失败,message 作为消息抛出
    返回值:如果找到,返回找到元素的对象
from selenium.webdriver import Chrome
import traceback
from selenium.webdriver.support.wait import WebDriverWait
driver = Chrome('./chromedriver')

# 3. 打开网址
# file://{本地网址绝对路径}
driver.get('http://www.baidu.com')


try:
    # time.sleep(2)
    # 1. 指定最长的等待时间,指定检测until函数的时间
    # driver对象,最长等待5s, 如果没有找到,每隔0.5s, 检测until()指定的函数,如果5s都没有找到,抛出异常
    wait_driver = WebDriverWait(driver, 5, 0.5)

    # WebDriverWait.until(), 需要传入一个函数名, 这个函数,参数为Chrome类型
    el = wait_driver.until(lambda temp: temp.find_element_by_tag_name('html'))
    print(el)

except Exception as e:
    # print(e) # 只打印错误信息
    print(traceback.format_exc()) # 有错误路径显示
finally:
    # 不管有没有异常,都保证driver可以关闭
    driver.quit()

隐式等待

隐式等待调用方法

driver.implicitly_wait(10)

隐式等待执行-说明

如果定位某一元素定位失败,那么就会触发隐式等待有效时长,如果在指定时长内加载完毕,则继续执行,否则抛出 NoSuchElementException 异常。

from selenium.webdriver import Chrome
from selenium.webdriver.support.wait import WebDriverWait
import traceback
import time

# 通过指定chromedriver的路径来实例化driver对象
driver = Chrome(executable_path='./chromedriver')

# 控制浏览器访问url地址
driver.get('https://www.baidu.com')

driver.implicitly_wait(5) # 隐式等待

try:
    driver.find_element_by_id('kw')

except Exception as e:
    print('type = ', type(e))
    # print(traceback.format_exc())
finally:
    # 退出浏览器
    driver.quit()

相关文章

网友评论

      本文标题:web自动化-selenium(一)

      本文链接:https://www.haomeiwen.com/subject/lfabkrtx.html