目录
多层框架/窗口定位
多层框架的定位
frame是什么?
多层窗口定位
层级定位
使用 XPath 进行层级定位:
使用 CSS 选择器进行层级定位:
下拉框处理
alert、confirm、prompt 的处理
Alert 弹窗:
Confirm 弹窗:
Prompt 弹窗:
DIV对话框的处理
上传文件操作
前面两章我们讲了一些元素定位方法和一些webdriver的常用api,今天这节我们来讲webdriver的另外一些常用的api,包括多层框架/窗口定位、层级定位、下拉框处理、alert、confirm、prompt 的处理、DIV对话框的处理、以及上传文件操作。🤷♀️
selenium+python环境没有配置好的可以先看我上两篇配置环境噢。
selenium环境配置: 自动化测试(一)配置selenium环境(带图文,防止踩坑)-CSDN博客
python环境配置: 自动化测试(前奏)Python环境配置教程(带图文)-CSDN博客
多层框架/窗口定位
对于一个web 应用,经常会出现框架(frame) 或窗口(window)的应用,这也就给我们的定位带来 了一定的困难。
定位一个frame :
driver.switch_to.frame(name_or_id_or_frame_element)
定位一个窗口window:
driver.switch_to.window(name_or_id_or_frame_element)
多层框架的定位
switch_to.frame(name_or_id_or_frame_element):通过frame的id或者name或者frame自带的其它 属性来定位框架,这里switch_to.frame()把当前定位的主体切换了frame里。
frame是什么?
<frame>
元素是 HTML 中用于定义框架(frameset)的一部分。它通常用于划分一个页面,将页面分割成多个区域,每个区域可以加载不同的文档。
在过去,网页设计中经常使用框架来创建具有不同功能的区域,例如一个包含导航菜单的框架、一个包含内容的框架等。然而,随着 HTML5 的发展,使用框架的做法已经逐渐减少,而被更灵活和语义化的元素所替代。
用以下HTML示例说明:
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>frame</title>
<link
href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstra
p-combined.min.css" rel="stylesheet" />
<script type="text/javascript">$(document).ready(function(){
});
</script>
</head>
<body>
<div class="row-fluid">
<div class="span10 well">
<h3>frame</h3>
<iframe id="f1" src="inner.html" width="800",
height="600"></iframe>
</div>
</div>
</body>
<script
src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.
min.js"></script>
</html>
inner.html
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>inner</title>
</head>
<body>
<div class="row-fluid">
<div class="span6 well">
<h3>inner</h3>
<iframe id="f2" src="http://www.baidu.com"
width="700"height="500"></iframe>
<a href="javascript:alert('watir-webdriver better than
selenium webdriver;')">click</a>
</div>
</div>
</body>
</html>
下面通过switch_to.frame() 方法来进行定位:
#coding=utf-8
from selenium import webdriver
import time
import os
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
file_path = 'file:///' + os.path.abspath('frame.html')
browser.get(file_path)
browser.implicitly_wait(30)
#先找到到ifrome1(id = f1)
browser.switch_to.frame("f1")
#再找到其下面的ifrome2(id =f2)
browser.switch_to.frame("f2")
#下面就可以正常的操作元素了
browser.find_element(By.ID,"kw").send_keys("selenium")
browser.find_element(By.ID,"su").click()
time.sleep(3)
browser.quit()
多层窗口定位
有可能嵌套的不是框架,而是窗口,还有真对窗口的方法:switch_to.window 用法与switch_to.frame 相同:
driver.switch_to.window("windowName")
示例:
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动浏览器并打开网页
driver = webdriver.Chrome()
driver.get("http://example.com")
# 打开新的窗口(可以是新标签页)
driver.execute_script("window.open('', '_blank');")
# 获取所有窗口句柄
all_handles = driver.window_handles
# 切换到新窗口
new_window_handle = [handle for handle in all_handles if handle != driver.current_window_handle][0]
driver.switch_to.window(new_window_handle)
# 在新窗口中执行操作
# 例如,可以在这里进行新窗口的元素定位和操作
driver.find_element(By.ID,"element_id").click()
# 切回原始窗口
driver.switch_to.window(all_handles[0])
# 关闭浏览器
driver.quit()
层级定位
层级定位是指在页面中嵌套的元素结构中定位到目标元素。这在网页中常见,特别是当你要定位的元素是另一个元素的子元素时。在 Selenium 中,你可以使用 XPath 或 CSS 选择器来执行层级定位。
使用 XPath 进行层级定位:
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动浏览器
browser = webdriver.Chrome()
# 打开网页
browser.get("https://www.example.com")
# 使用 XPath 定位嵌套的元素
nested_element = browser.find_element(By.XPATH,"//div[@id='parent']/input[@name='child']")
# 在找到的元素上执行操作
nested_element.send_keys("Hello, Selenium!")
# 关闭浏览器
browser.quit()
在这个例子中,XPath表达式 //div[@id='parent']/input[@name='child']
表示找到ID为 'parent' 的 <div>
元素下的名为 'child' 的 <input>
元素。
使用 CSS 选择器进行层级定位:
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动浏览器
browser = webdriver.Chrome()
# 打开网页
browser.get("https://www.example.com")
# 使用 CSS 选择器定位嵌套的元素
nested_element = browser.find_element(By.CSS_SELECTOR,"div#parent input[name='child']")
# 在找到的元素上执行操作
nested_element.send_keys("Hello, Selenium!")
# 关闭浏览器
browser.quit()
在这个例子中,CSS 选择器 div#parent input[name='child']
表示找到ID为 'parent' 的 <div>
元素下的名为 'child' 的 <input>
元素。
注意:在使用层级定位时,请确保选择器或 XPath 表达式足够具体,以确保准确定位到目标元素,避免选择到其他不符合预期的元素。
下拉框处理
下拉框是我们最常见的一种页面元素,对于一般的元素,我们只需要一次就定位,但下拉框里的内容需 要进行两次定位,先定位到下拉框对下拉框进行操作后,再定位到下拉框内里的选项。
q:假设有一个选项框,选择地点,里面有北京,上海,广州,深圳,刚开始北上广深都没显示,只显示一个下拉框你得点击那个下拉框才显示北上广深,这该如何定位呢?
选项框:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Location Selector</title>
</head>
<body>
<label for="location">选择地点:</label>
<select id="location" name="location">
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
<option value="shenzhen">深圳</option>
</select>
</body>
</html>
a:对于这样的下拉框,我们可以使用 Selenium 来模拟点击下拉框并选择其中的选项。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 启动浏览器
driver = webdriver.Chrome()
# 打开网页
driver.get("path/to/your/html/file")
# 等待下拉框可见
dropdown = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "location"))
)
# 点击下拉框
dropdown.click()
# 选择其中的选项,比如选择 "上海"
shanghai_option = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.XPATH, "//option[text()='上海']"))
)
shanghai_option.click()
# 关闭浏览器
driver.quit()
我们在上面的例子中使用了 WebDriverWait
来等待元素可见,然后分别点击下拉框和选择 "上海" 这个选项。
alert、confirm、prompt 的处理
在 Selenium 中,对于网页上的 alert
、confirm
和 prompt
弹窗,可以使用 Alert
类来进行处理。这些弹窗通常是由 JavaScript 代码触发的,而 Selenium 提供了专门的方法来处理这些弹窗。
弹窗就是类似于这个:
1. text 返回alert/confirm/prompt 中的文字信息
2. accept 点击确认按钮
3. dismiss 点击取消按钮,如果有的话
3. send_keys 输入值,如果alert 没有对话框就不能用了,不然会报错
Alert 弹窗:
Alert
弹窗是简单的信息提示框,通常只包含一个确定按钮。
使用 switch_to.alert
进入弹窗,然后使用 accept()
方法点击确定按钮
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
alert = driver.switch_to.alert
alert.accept()
driver.quit()
Confirm 弹窗:
Confirm
弹窗与 Alert
类似,但包含确定和取消两个按钮。
使用 switch_to.alert
进入弹窗,然后可以使用 accept()
方法点击确定按钮,或使用 dismiss()
方法点击取消按钮。
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
confirm = driver.switch_to.alert
confirm.accept() # 或 confirm.dismiss()
driver.quit()
Prompt 弹窗:
Prompt
弹窗包含一个文本输入框,可以输入文本,并有确定和取消两个按钮。
使用 switch_to.alert
进入弹窗,可以使用 send_keys()
方法输入文本,然后使用 accept()
方法点击确定按钮,或使用 dismiss()
方法点击取消按钮。
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
prompt = driver.switch_to.alert
prompt.send_keys("Hello, Selenium!")
prompt.accept() # 或 prompt.dismiss()
driver.quit()
DIV对话框的处理
如果页面元素比较多,利用元素的属性无法准确的定位这个元素的时候,我们可以先定位元素所在的 div块,再去定位这个元素。
用以下HTML示例说明:演示如何通过先定位父级元素再定位子元素的方式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Parent Element Example</title>
<style>
/* 包含多个元素的父级容器 */
.parent-container {
border: 1px solid #ddd;
padding: 10px;
}
/* 子元素 */
.target-element {
background-color: #aaf;
padding: 5px;
margin: 5px;
}
</style>
</head>
<body>
<!-- 包含多个元素的父级容器 -->
<div class="parent-container">
<p class="target-element">第一个元素</p>
<p class="target-element">第二个元素</p>
<p class="target-element">第三个元素</p>
</div>
</body>
</html>
Python 代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("path/to/your/html/file")
# 定位包含多个元素的父级容器
parent_container = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "parent-container"))
)
# 在父级容器中定位子元素(这里选择第二个元素)
target_element = parent_container.find_element(By.XPATH, "(//p[@class='target-element'])[2]")
# 执行操作,比如获取文本内容
element_text = target_element.text
print("Text of the second element:", element_text)
driver.quit()
上传文件操作
文件上传操作也比较常见功能之一,上传功能没有用到新有方法或函数,关键是思路。
上传过程一般要打开一个本地窗口,从窗口选择本地文件添加。所以,一般会卡在如何操作本地窗口添加上传文件。 其实,在selenium webdriver 没我们想的那么复杂;只要定位上传按钮,通过send_keys 添加本地文 件路径就可以了。绝对路径和相对路径都可以,关键是上传的文件存在。
HTML 代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File Upload Example</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<label for="fileInput">选择文件:</label>
<input type="file" id="fileInput" name="file">
<input type="submit" value="上传">
</form>
</body>
</html>
Python 代码:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("path/to/your/html/file")
# 定位上传文件的 input 元素
file_input = driver.find_element(By.ID,"fileInput")
# 指定要上传的文件路径
file_path = "/path/to/your/file.txt"
# 使用 send_keys() 方法上传文件
file_input.send_keys(file_path)
# 等待一定时间,以确保文件上传完成
driver.implicitly_wait(5)
# 提交表单或执行其他操作(这里以点击提交按钮为例)
submit_button = driver.find_element(By.CSS_SELECTOR,"input[type='submit']")
submit_button.click()
# 关闭浏览器
driver.quit()
在这个例子中,使用find_element(By.ID,"fileInput")方法定位到上传文件的 input 元素,然后使用 send_keys()
方法指定要上传的文件路径。接着,等待一定时间以确保文件上传完成,最后通过点击提交按钮或执行其他相关操作。
好了,常见的webdriver的api已经告诉大家了,后期我会给大家带来python中的自动化测试之unittest框架,这也是新的开始,溯洄从之,道阻且长!
本节就到这里啦,你们的支持就是我前进的动力,希望大家多多支持噢🤦♀️🤦♂️🤷♀️🤷♂️🎈