selenium自动化测试-等待和窗口切换详解

目录

等待

强制等待

隐式等待

显式等待

窗口切换

标签页切换

iframe切换

alert弹窗切换


等待

在打开网页后,可能页面中某些元素在加载中,导致定位元素时找不到对应元素,然后报错出现异常,因此我们需要打开网页后,设置等待时间

一共有三种等待方式:强制等待、隐式等待、显式等待

强制等待

使用方法:

import time
#强制等待
time.sleep(delay-time)

delay-time的单位为,delay设置多少秒页面就会等待多少秒。(死等,不会有任何动作)

使用举例:

打开百度,然后过3秒,再定位搜索框输入python并点击搜索,该过程我上一章清晰的介绍了,如果看不懂可以去我上一章查看

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

driver = webdriver.Edge()

#强制等待
time.sleep(3)

input = driver.find_element(By.ID,"kw")
input.send_keys("python")
input.send_keys(Keys.ENTER)

#此处是为了防止计时结束后,还没看到搜索结果就结束了
time.sleep(3)

driver.close()

一般不建议使用此方法,会严重影响程序运行时间 

隐式等待

使用方法:

implicitly_wait(delay-time)

delay-time的单位为秒

隐式等待会设置一个超时时间,在超时时间段内,必须网页的全部元素加载完成才能继续执行下一步,否则会一直等待,直至超时才会执行下一步

这样做的一个弊端就是,有个别元素加载的非常慢,而大部分以及我们想操作的元素已经加载好了,但我们依然需要等待,直至超时,即计时结束

这里我们同样也是想要打开百度,然后搜索selenium,选择所有h3标签下class=‘’t”下的所有为a标签的元素

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Edge()
# 打开百度首页
driver.get(r'https://www.baidu.com/')
#使用css选择器和id都可以,#代表选择具有id属性的元素
driver.find_element(By.CSS_SELECTOR,"#kw").send_keys("selenium")
driver.find_element(By.ID,"su").click()
# 隐式等待15秒
driver.implicitly_wait(15)
result = driver.find_elements(By.CSS_SELECTOR,"h3.t>a")
for i in result:
    print(i.text)
# 退出
driver.quit()

然后这样在加载好后就获取到了我们想要的结果

显式等待

上面说了隐式等待的弊端,是必须等待网页中全部元素加载完毕才可以进行下一步。那显式等待就是为了解决这个问题。

显示等待又称作条件等待,只要在设置的超时时间段内,我想要的元素加载好了,那就直接进行下一步,而不用等待其他元素全部加载完了。如果过了超时时间,则会抛出异常TimeoutException

这是代码原型

WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)

主要有4个参数:

driver:浏览器驱动

timeout:等待时间

poll_frequency:检测的间隔时间,默认0.5s

ignored_exceptions:超时后的异常信息,默认抛出NoSuchElementException

用法示例:

我们打开百度搜索selenium,然后查找class=“tt”的,其实没有c这个属性的,因此5秒之后。会超时结束,然后报错

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
driver = webdriver.Edge()
# 打开百度首页
driver.get(r'https://www.baidu.com/')
driver.find_element(By.CSS_SELECTOR,"#kw").send_keys("selenium")
driver.find_element(By.CSS_SELECTOR,"#su").click()
# 超时时间为5秒,每0.2秒检查1次,直到class="tt"的元素出现
text = WebDriverWait(driver,5,0.2).until(lambda x:x.find_element(By.CSS_SELECTOR,".tt")).text

# 退出
driver.quit()

可以发现报了一个超时错误 

窗口切换

标签页切换

当我们打开一个网页后,点击一个链接,可能会进入一个新的页面,但是此时我们依然想返回到原来的界面该怎么做呢?

这里使用到了

switch_to.window()这个函数

这个函数可以切换到指定标签页(窗口)

我们可以先记录下当前窗口curWindow,然后点击链接,进入新的窗口后,我们再switch_to.window到刚保存的curWindow即可

注意:当打开并进入新页面时,你的句柄仍然在上一个页面!

比如我在页面1 新打开并进入了页面2,此时我的页面是2,但是我的句柄依然在页面1,因此current_window_handle得到的是1的句柄

所以此时我们直接switch_to.window()就可以返回刚才的界面,即1

下面以打开qq网举例:

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait

driver = webdriver.Edge()

driver.get("http://qq.com")

driver.maximize_window()
driver.find_element(By.XPATH,"//li/a[contains(text(),'要闻')]").click()
#获取当前句柄(首页),虽然进入了要闻界面,但句柄依然在刚才的首页!!
curWindow = driver.current_window_handle
#转到刚才的句柄,此时会在首页
driver.switch_to.window(curWindow)

time.sleep(3)

driver.close()

还有另一种方法:

获取全部的窗口句柄,然后保存当前窗口的句柄,然后循环遍历这些窗口句柄,直到与保存的相等,我们在switch_to.window到这个窗口

举个例子:

我们打开腾讯网首页,然后点击左上角的要闻,此时我们会进入新的窗口。我们保存下当前窗口句柄(首页),然后我们再获得全部的窗口,再循环遍历,直到找到与其相等的

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait

driver = webdriver.Edge()

driver.get("http://qq.com")

driver.maximize_window()
driver.find_element(By.XPATH,"//li/a[contains(text(),'要闻')]").click()

#得到当前窗口句柄
curWindow = driver.current_window_handle
#得到所有的窗口句柄
windows = driver.window_handles
for iWindow in windows:
    if iWindow == curWindow:
        driver.switch_to.window(iWindow)

iframe切换

iframe窗口是在一个html界面中又嵌套了一个html界面,我们如果要对嵌套的这个iframe中的元素进行操作,那么就必须要先切换这个iframe窗口才可以进行操作。

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time


driver = webdriver.Edge()

driver.get("https://connect.qq.com/")
driver.maximize_window()
# 等待元素可见
login_btn_loc = (By.XPATH, '//div[@class="no-login"]/a')
WebDriverWait(driver, 30).until(EC.presence_of_element_located(login_btn_loc))
# 点击登录按钮
driver.find_element(*login_btn_loc).click()

# 等待frame加载到dom树中
frame_loc = (By.XPATH, '//*[@id="login_frame"]')
WebDriverWait(driver, 30).until(EC.presence_of_element_located(frame_loc))

# 切换到frame上,切换到frame上时,可以以三种形式传入参数:name属性,下标,webelement对象
# 切换到frame,传入 webelement对象
driver.switch_to.frame(driver.find_element(By.XPATH,'//*[@id="login_frame"]'))

driver.find_element(By.XPATH,"//div[@id='bottom_web']/a[text()='注册账号']").click()

time.sleep(2)
driver.close()

alert弹窗切换

有时候浏览器可能会弹出一些提示,如果我们不处理,便无法进行下一步。alert窗口就是js提示框,它不属于web界面

它对于alert弹窗有4种处理方式

driver.switch_to.alert.accept()  # 确定操作
driver.switch_to.alert.dismiss()    # 取消操作
driver.switch_to.alert.send_keys("")    # alert弹框输入文本
driver.switch_to.alert.text()      # 获取alert的文本内容

因为没有可以演示的网站,大家可以自己在桌面创建一个.txt文本文件,复制以下html代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Alert 弹窗示例</title>
</head>
<body>

<button onclick="showAlert()">显示 Alert 弹窗</button>

<script>
function showAlert() {
    alert("你好啊");
}
</script>

</body>
</html>

然后可以使用刚才的函数,比如我想点击确定,便可以这样写:

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time


driver = webdriver.Edge()
#这个路径为你电脑上刚才创建的文件的路径
driver.get("C:/Users/h/Desktop/aa.html")

driver.find_element(By.XPATH,"//button").click()

#确定
driver.switch_to.alert.accept()


time.sleep(3)

同样,如果我们怕alert弹窗不能及时加载出来,我们可以设置条件等待,条件是直到alert弹出显示

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time


driver = webdriver.Edge()
driver.get("C:/Users/h/Desktop/aa.html")

driver.find_element(By.XPATH,"//button").click()

# driver.switch_to.alert.accept()
WebDriverWait(driver,10,1).until(EC.alert_is_present()).accept()

time.sleep(3)

这样便完成了alert弹窗的处理

本文到这里就结束了,主要讲了对selenium的等待和弹窗的处理,如果有不明白,欢迎留言或私信哦~

相关推荐

  1. Selenium自动化测试入门:设置等待时间

    2024-07-19 03:58:02       26 阅读
  2. UI自动化Selenium 页面窗口window定位切换

    2024-07-19 03:58:02       53 阅读
  3. Selenium 切换窗口

    2024-07-19 03:58:02       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-19 03:58:02       70 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-19 03:58:02       74 阅读
  3. 在Django里面运行非项目文件

    2024-07-19 03:58:02       62 阅读
  4. Python语言-面向对象

    2024-07-19 03:58:02       72 阅读

热门阅读

  1. 一个菜鸟如何在苹果笔记本上学C语言

    2024-07-19 03:58:02       27 阅读
  2. 中西入门哲学史差异记录

    2024-07-19 03:58:02       20 阅读
  3. GitHub敏感信息扫描工具

    2024-07-19 03:58:02       26 阅读
  4. 7大并发容器种类原理解析与应用

    2024-07-19 03:58:02       22 阅读
  5. mstar 开发环境搭建

    2024-07-19 03:58:02       23 阅读
  6. Jupyter Notebook: 是一个强大的交互式计算

    2024-07-19 03:58:02       28 阅读
  7. String、StringBuilder 和 StringBuffer 有什么区别?

    2024-07-19 03:58:02       25 阅读
  8. Windows图形界面(GUI)-DLG-C/C++ - 树形视图(TreeView)

    2024-07-19 03:58:02       27 阅读
  9. 正则表达式

    2024-07-19 03:58:02       24 阅读
  10. 网络同步学习(状态同步,帧同步)

    2024-07-19 03:58:02       24 阅读