简介

selenium是一个用于Web应用程序测试的工具。selenium测试直接运行于浏览器网页上,可以模拟用户操作网页。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera,Edge等。

Selenium 能够实现的功能包括:定位网页元素、模拟点击、滑动、键盘输入等等操作。



selenium 支持的语言包括:

  • Python
  • CSharp
  • Ruby
  • JavaScript
  • Kotlin

本教程以python操作selenium为例,说明selenium的使用方法。

简单使用

selenium 是第三方模块,首先安装该模块

pip install selenium >= 4.10.0

selenium模块 一共有4个大的版本,最新的4.x版本和之前的版本在语法上有较大的变化,所以安装最新的4.x版本,避免低版本带来的混乱。

打开浏览器请求网页

import time
from selenium import webdriver driver = webdriver.Chrome() # 初始化浏览器
driver.get("https://www.v2fy.com/game/tetris/") # 请求网页 time.sleep(10) # 为避免直接退出,睡眠10s

执行该代码,打开chrome浏览器,请求网页

操作网页元素

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome()
driver.get("https://www.baidu.com") search_input = driver.find_element(By.NAME, "wd")
search_query = "python selenium"
search_input.send_keys(search_query)
search_input.send_keys(Keys.ENTER) time.sleep(10)

操作网页的原理就是首先根据元素name定位找到了输入框

search_input = driver.find_element(By.NAME, "wd")  # 定位名字叫wd的元素,也就是输入框

然后向输入框填充 python selenium,

search_query = "python selenium"
search_input.send_keys(search_query)

最后触发输入框的回车键。

search_input.send_keys(Keys.ENTER)

selenium 拥有的能力简单来说就是定位html中元素,操作元素。

元素定位

selenium 可以定位网页中元素,其拥有的方法和JavaScript类似,可以通过元素的特征定位,一共拥有8种定位元素的方法,分别是:

driver.find_element(By.ID,'ID')
driver.find_element(By.TAG_NAME,'NAME')
driver.find_element(By.CLASS_NAME,'CLASS_NAME')
driver.find_element(By.XPATH,'XPATH')
driver.find_element(By.TAG_NAME,'TAG_NAME')
driver.find_element(By.CSS_SELECTOR,'CSS_SELECTOR')
driver.find_element(By.LINK_TEXT,'LINK_TEXT')
driver.find_element(By.PARTIAL_LINK_TEXT,'PARTIAL_LINK_TEXT')
  • 根据元素ID定位
  • 根据元素name定位
  • 根据元素class_name定位
  • 根据元素xpath定位
  • 根据元素tag_name定位
  • 根据元素css定位
  • 根据超链接文本定位

ID

在id定位里,会返回第一个id属性匹配的元素,如果没有元素匹配,会抛出NoSuchElementException异常。

<html>
<body>
<form id="loginForm">
<input name="username" type="text" />
<input name="password" type="password" />
<input name="continue" type="submit" value="Login" />
</form>
</body>
<html>

可以这样定位表单元素form:

from selenium.webdriver.common.by import By

login_form = driver.find_element(By.ID 'loginForm')

Name

在name定位里,会返回第一个name属性匹配的元素,如果没有元素匹配,会抛出NoSuchElementException异常。

<html>
<body>
<form id="loginForm">
<input name="username" type="text" />
<input name="password" type="password" />
<input name="continue" type="submit" value="Login" />
</form>
</body>
<html>

username 和 password元素 可以这样定位:

from selenium.webdriver.common.by import By

username = driver.find_element(By.NAME, 'username')
password = driver.find_element(By.NAME, 'password')

class_name

知道class就使用这个定位,只返回匹配的第一个,无元素匹配,会抛出NoSuchElementException异常。

实例:

<html>
<body>
<p class="content">Site content goes here.</p>
</body>
<html>

定位p元素:

content = driver.find_element(By.CLASS_NAME, 'content')

xpath

XPath是用来定位XML文档节点的语言。不过HTML可以看成是XML(XHTML)的一种实现。selenium用户可以使用这个强力的语言来瞄准Web应用的元素。 XPath延伸了用id或者name属性来定位的单一方法,开创了许多可能性,例如定位页面的第三个复选框

用XPath的主要理由之一,就是你想定位的元素没有合适的id或者name属性的时候,你可以用XPath来对元素进行绝对定位(不推荐)或者把这个元素和另外一个有确定id或者name的元素关联起来(即相对定位)。XPath定位器也可以用来找出那些具有id,name以外属性的元素。

<html>
<body>
<form id="loginForm">
<input name="username" type="text" />
<input name="password" type="password" />
<input name="continue" type="submit" value="Login" />
<input name="continue" type="button" value="Clear" />
</form>
</body>
<html>

form元素可以这样定位:

login_form = driver.find_element(By.xpath, "/html/body/form[1]")
login_form = driver.find_element(By.xpath, "//form[1]")
login_form = driver.find_element(By.xpath,"//form[@id='loginForm']")

这里下标表示是从1开始的

  1. 绝对路径(如果HTML有细微的改变就会失效)
  2. HTML的第一个form元素
  3. id属性为'loginForm'的form元素

username元素可以这样定位:

username = driver.find_element(By.xpath,"//from[input/@name='username']")
username = driver.find_element(By.xpath,"//form[@id='loginForm']/input[1]")
username = driver.find_element(By.xpath,"//input[@name='username']")
  1. 第一个form元素的 name属性是'username'的input子元素
  2. id属性为'loginForm'的form元素的第一个input子元素
  3. name属性为'username'的第一个input元素

clear 按钮可以这样定位:

clear_button = driver.find_element(By.xpath, "//input[@name='continue'][@type='button']")
clear_button = driver.find_element(By.xpath, "//form[@id='loginForm']/input[4]")
  1. type属性为'button',name属性为'continue'的第一个input元素
  2. id为'loginForm'的表单的第四个input子元素

tag_name

知道元素标签名就使用这个定位,如果没有元素匹配,会抛出NoSuchElementException异常。

实例:

<html>
<body>
<h1>Welcome</h1>
<p>Site content goes here.</p>
</body>
<html>

可以这样定位标题元素(h1):

heading1 = driver.find_element(By.TAG_NAME, 'h1')

css

如果你能用css选择器的语法来表述一个元素,那么就选这个,只返回匹配的第一个,无元素匹配,会抛出NoSuchElementException异常。

实例:

<html>
<body>
<p class="content">Site content goes here.</p>
</body>
<html>

定位p元素:

content = driver.find_element(By.CSS_SELECTOR, 'p.content')

Link text

链接标签使用了什么文本,那么通过链接的文本进行定位。在超链接定位里,会返回第一个文本属性匹配的链接,如果没有元素匹配,会抛出NoSuchElementException异常。

实例:

<html>
<body>
<p>Are you sure you want to do this?</p>
<a href="continue.html">Continue</a>
<a href="cancel.html">Cancel</a>
</body>
<html>

可以这样定位 continue.html链接:

# LINK_TEXT 需要完全匹配
continue_link = driver.find_element(By.LINK_TEXT, 'Continue') # PARTIAL_LINK_TEXT 可以模糊匹配
continue_link = driver.find_element(By.PARTIAL_LINK_TEXT, 'Conti')

知识加油站: find_element 方法特点是查找到匹配的元素,返回第一个。如果想返回所有的元素可以使用方法find_elements。参考"登录算法仓"中的使用。

网页动作

用selenium做自动化,有时候会遇到需要模拟鼠标操作才能进行的情况,比如单击、双击、点击鼠标右键、拖拽等等。而selenium给我们提供了一个类来处理这类事件——ActionChains。ActionChains 能够模拟键盘、鼠标等设备的操作。

ActionChains基本用法

首先需要了解ActionChains的执行原理,当你调用ActionChains的方法时,不会立即执行,而是会将所有的操作按顺序存放在一个队列里,当你调用perform()方法时,队列中的时间会依次执行。

这种情况下我们可以有两种调用方法:

链式写法

menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")
ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()

分步写法

menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")
actions = ActionChains(driver)
actions.move_to_element(menu)
actions.click(hidden_submenu)
actions.perform()

两种写法本质是一样的,ActionChains都会按照顺序执行所有的操作。

动作列表

Click

Click 模拟鼠标左键的点击事件,也就是最常用的鼠标点击

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains driver = webdriver.Chrome()
driver.get("http://www.usey.cn/hex") # 向转换数字输入框中输入1024
search_input = driver.find_element(By.ID, "ipt_hex")
search_input.send_keys("1024")
time.sleep(3) # 定位转换按钮
send_btn = driver.find_element(By.CLASS_NAME, "btn-primary") # 点击转换按钮
ActionChains(driver).click(send_btn).perform()
time.sleep(10)

key_down key_up

key_down动作是按下一个按键,对应的key_up是释放一个按键。通常这两个操作时成对出现的。模拟在数据框中以shfit + 小写字母 输入,将小写字母变成大写字母。

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains driver = webdriver.Chrome()
driver.get("https://www.baidu.com/")
time.sleep(3) search_input = driver.find_element(By.ID, "kw") ActionChains(driver).key_down(Keys.SHIFT) actions = ActionChains(driver) # 模拟按下 Shift 键
actions.key_down(Keys.SHIFT) # 在输入框中输入文字
actions.send_keys_to_element(search_input, "hello world") # 模拟释放 Shift 键
actions.key_up(Keys.SHIFT) # 执行以上的操作
actions.perform() time.sleep(10)

send_keys

send_keys的功能有两个:

  1. 向当前元素发送文字
  2. 向当前元素发送按键

    在搜索框上有两种方法可以触发搜索,一种是点击搜索按钮;另一种是搜索框绑定回车键。其中bing.com支持第二种方法,所以可以在输入框输入完成之后发送回车按键完成搜索。
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains driver = webdriver.Chrome()
driver.get("https://www.bing.com/")
time.sleep(3) search_input = driver.find_element(By.ID, "sb_form_q")
search_input.send_keys("中国最大的城市")
search_input.send_keys(Keys.ENTER) time.sleep(10)

等待

为什么要使用等待?

在自动化测试脚本的运行过程中,webdriver操作浏览器的时候,对于元素的定位是有一定的超时

时间,大致在1-3秒

如果这个时间内仍然定位不到元素,就会抛出异常,中止脚本执行

我们可以通过在脚本中设置等待的方式来避免由于网络延迟或浏览器卡顿导致的偶然失败

常用的三种等待方式

  • 强制等待
  • 隐式等待
  • 显示等待

强制等待

利用time模块的sleep方法来实现,最简单粗暴的等待方法

强制等待,不管你浏览器是否加载完成,都得给我等待3秒,3秒一到,继续执行下面的代码

# -*- coding: utf-8 -*-

import time
from selenium import webdriver
driver = webdriver.Chrome()
# 打开百度首页
driver.get(r'https://www.baidu.com/')
# 强制等待3秒
time.sleep(3)
driver.find_element_by_css_selector("#kw").send_keys("selenium")
# 退出
driver.quit()

弊端

不建议用这种等待方法,严重影响代码的执行速度

隐式等待

implicitly_wait()方法用来等待页面加载完成(直观的就是浏览器tab页上的小圈圈转完)网页加载完成则执行下一步

隐式等待只需要声明一次,一般在打开浏览器后进行声明。声明之后对整个drvier的生命周期都有效,后面不用重复声明

import time
from selenium import webdriver
driver = webdriver.Chrome()
# 打开百度首页
driver.get(r'https://www.baidu.com/')
# 隐性等待5秒
driver.implicitly_wait(5)
driver.find_element_by_css_selector("#kw").send_keys("selenium")
# 退出
driver.quit()

弊端

程序会一直等待整个页面加载完成,直到超时

有时候我需要的那个元素早就加载完成了,只是页面上有个别其他元素加载特别慢,我仍要等待页

面全部加载完成才能执行下一步

显示等待

WebDriverWait,配合该类的until()和until_not()方法,就能够根据判断条件而进行灵活地等待了。

它主要的意思就是:程序每隔xx秒看一眼,如果条件成立了,则执行下一步。否则继续等待,直到超过设置的最长时间,然后抛出TimeoutException。

显示等待必须在每个需要等待的元素前面进行声明

class WebDriverWait:
def __init__(
self,
driver,
timeout: float,
poll_frequency: float = POLL_FREQUENCY,
ignored_exceptions: typing.Optional[WaitExcTypes] = None,
):
pass

参数说明:

  • driver:浏览器驱动
  • timeout:等待时间
  • poll_frequency:检测的间隔时间,默认0.5s
  • ignored_exceptions:超时后的异常信息,默认抛出NoSuchElementException

打开b站鬼畜区示例

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Chrome()
driver.get("https://www.bilibili.com/")
time.sleep(3) login_btn = WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located((By.LINK_TEXT, "鬼畜")))
#点击元素
login_btn.click() time.sleep(10)

显示等待常用方法

#判断当前页面的title是否精确等于预期,返回布尔值
WebDriverWait(driver,10).until(EC.title_is("百度一下,你就知道")) #判断当前页面的title是否包含预期字符串,返回布尔值
WebDriverWait(driver,10).until(EC.title_contains('new')) #判断当前页面的url是否精确等于预期,返回布尔值
WebDriverWait(driver,10).until(EC.url_contains('https://www.baidu.com')) #判断当前页面的url是否包含预期字符串,返回布尔值
WebDriverWait(driver,10).until(EC.url_contains('baidu')) #判断当前页面的url是否满足字符串正则表达式匹配,返回布尔值
WebDriverWait(driver,10).until(EC.url_matches('.+baidu.+')) #判断元素是否出现,只要有一个元素出现,返回元素对象
WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,'kw'))) #判断元素是否可见,返回元素对象
WebDriverWait(driver,10).until(EC.visibility_of(driver.find_element(By.ID,'kw'))
) #判断元素是否包含指定文本,返回布尔值
WebDriverWait(driver,10).until(EC.text_to_be_present_in_element((By.NAME,'tj_trn
ews'),'新闻')) #判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去
WebDriverWait(driver,10,).until(EC.frame_to_be_available_and_switch_to_it(By.xpa
th,'//iframe')) #判断某个元素是否可见并且是可点击的,如果是的就返回这个元素,否则返回False
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.NAME,'tj_trnews'))
) #判断某个元素是否被选中,一般用在下拉列表
WebDriverWait(driver,10).until(EC.element_to_be_selected(driver.find_element(By.
xpath,'//input[@type="checkbox"]'))) #判断页面上是否存在alert,如果有就切换到alert并返回alert的内容
WebDriverWait(driver,10).until(EC.alert_is_present())

selenium 开源UI测试工具的更多相关文章

  1. 2014 非常好用的开源 Android 测试工具

    http://www.php100.com/html/it/mobile/2014/1015/7495.html 当前有很大的趋势是转向移动应用平台,Android 是最广泛使用的移动操作系统,201 ...

  2. 开源负载测试工具k6比JMeter更容易的5件事

    k6是GitHub上提供的开源负载测试工具.它是用Go编写的,并运行用JavaScript编写的测试脚本.它受到了开发人员,测试人员和DevOps团队的强烈兴趣,并拥有超过4400名GitHub明星. ...

  3. 推荐10款免费的在线UI测试工具

    发布网站之前至关重要的一步是网站测试.网站测试要求我们全面地运行网站并通过所有基本测试,如响应式设计测试.安全测试.易用性测试.跨浏览器兼容性.网站速度测试等. 网站测试对SEO.搜索引擎排名.转换率 ...

  4. 开源API测试工具 Hitchhiker v0.8 - 自动化测试结果统计

    Hitchhiker 是一款开源的支持多人协作的 Restful Api 测试工具,支持自动化测试, 数据对比,压力测试,支持脚本定制请求,可以轻松部署到本地,和你的team成员一起协作测试Api. ...

  5. 开源Web测试工具介绍

    HtmlUnitHtmlUnit 是 JUnit 的扩展测试框架之一.HtmlUnit 将返回文档模拟成 HTML,这样您便可以直接处理这些文档了.HtmlUnit 使用例如 table.form 等 ...

  6. 开源API测试工具 Hitchhiker v0.4更新 - 没有做不到,只有想不到

    Hitchhiker 是一款开源的 Restful Api 测试工具,支持Schedule, 数据对比,压力测试,支持上传脚本定制请求,可以轻松部署到本地,和你的team成员一起管理Api. 详细介绍 ...

  7. 开源API测试工具 Hitchhiker v0.5更新 - 完善细节

    Hitchhiker 是一款开源的支持多人协作的 Restful Api 测试工具,支持Schedule, 数据对比,压力测试,支持上传脚本定制请求,可以轻松部署到本地,和你的team成员一起管理Ap ...

  8. 开源API测试工具 Hitchhiker v0.6更新 - 改进压力测试

    Hitchhiker 是一款开源的支持多人协作的 Restful Api 测试工具,支持Schedule, 数据对比,压力测试,支持上传脚本定制请求,可以轻松部署到本地,和你的team成员一起协作测试 ...

  9. 开源API测试工具 Hitchhiker v0.7更新 - Schedule的对比diff

    Hitchhiker 是一款开源的支持多人协作的 Restful Api 测试工具,支持Schedule, 数据对比,压力测试,支持脚本定制请求,可以轻松部署到本地,和你的team成员一起协作测试Ap ...

  10. 开源API测试工具 Hitchhiker v0.10 - 中文版

    Hitchhiker 是一款开源的支持多人协作的 Restful Api 测试工具,支持自动化测试, 数据对比,压力测试,支持脚本定制请求,可以轻松部署到本地,和你的team成员一起协作测试Api. ...

随机推荐

  1. 面向对象java前三次pta作业

    目录: 1.前言 2.设计与分析 3.踩坑心得 4.主要困难及改进建议 5.总结 1.前言 面向对象程序设计(Object-Oriented Programming,简称OOP)是一种编程范式,它以对 ...

  2. 微信小程序记住密码,让登录解放双手

    密码是用户最重要的数据,也是系统最需要保护的数据,我们在登录的时候需要用账号密码请求登录接口,如果用户勾选记住密码,那么下一次登录时,我们需要将账号密码回填到输入框,用户可以直接登录系统.我们分别对这 ...

  3. FP-Growth算法全解析:理论基础与实战指导

    本篇博客全面探讨了FP-Growth算法,从基础原理到实际应用和代码实现.我们深入剖析了该算法的优缺点,并通过Python示例展示了如何进行频繁项集挖掘. 关注TechLead,分享AI全维度知识.作 ...

  4. 【结对作业】 第一周 | 学习体会day05

    实现了单条地铁线路的直达 进行了页面的优化,实现了侧边栏功能 并且对第二天(今天)的任务进行了规划.

  5. [CF1854C] Expected Destruction

    题目描述 You have a set $ S $ of $ n $ distinct integers between $ 1 $ and $ m $ . Each second you do th ...

  6. 生成式AI:未来的发展方向是什么?

    生成式AI的问世标志着人工智能领域迎来了一个全新时代的开启.今年,ChatGPT的面世引起了广泛的热议和关注,许多人认为这标志着人工智能领域进入了一个大规模探索的时代.然而,事实上,这只是生成式AI发 ...

  7. 华企盾科技:智能AI自动化研判分析服务系统概述

    由中企网安全资子公司北京华企盾科技有限责任公司开发的<智能AI自动化研判分析服务系统>,获得国家版权局颁发的计算机软件著作权登记证书. 智能AI自动化研判分析服务系统是基于人工智能.大数据 ...

  8. Matrix-writeup

    matrix 信息收集 只开放了80端口 换了一个大一点的字典扫到了一个PHP页面 此页面会将输入的内容显示在页面上,抓包之后可以看到他写入到了一个txt文件中 那就可以把一句话写入到一个文件里再去连 ...

  9. redis + AOP + 自定义注解实现接口限流

    限流介绍 限流(rate limiting) ​ 是指在一定时间内,对某些资源的访问次数进行限制,以避免资源被滥用或过度消耗.限流可以防止服务器崩溃.保证用户体验.提高系统可用性. 限流的方法有很多种 ...

  10. Python——第四章:内置函数(下)

    内置函数的使用方法: locals:函数会以字典的类型返回当前位置的所有局部变量 globals:函数会以字典的类型返回全部局部变量 zip: 可以把多个可迭代内容进行合并 sorted: 排序 fi ...