目录
等待
强制等待
隐式等待
显式等待
窗口切换
标签页切换
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的等待和弹窗的处理,如果有不明白,欢迎留言或私信哦~