三大等待与三大切换
selenium之三大等待与三大切换
- 三大等待(强制等待,隐形等待,显性等待)
- 三大切换(iframe(内嵌),window,alert(弹框))
详解三大等待
3.1 三大等待之强制等待
sleep(s秒) 让程序死等s秒,无论发生任何事情,s秒后继续执行后续代码
当我们的操作带来了页面的变化,那么一定需要等待(否则代码的稳定性很差)1
2
3
4
5
6from selenium import webdriver
from time import sleep
# 浏览器会话的开始
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
sleep(3) # 傻傻等3秒3.2 三大等待之隐形等待
隐形等待:如果你10秒出现啦,我就开始下一步操作,设置上限:30秒,超时就报错:TimeoutException
设置最长的等待时间,可以自主判断,整个driver会话周期,设置一次,全局可用 (driver.get()—driver.quite())
implicitly_wait(s秒) driver会话周期:开始调用浏览器(浏览器会话的开始)—浏览器会话的结束(关闭浏览器则关闭了chromedriver)1
2
3
4
5
6
7
8
9from selenium import webdriver
# 浏览器会话的开始
driver = webdriver.Chrome()
# 设置全局等待
driver.implicitly_wait(30) # 所有存在find_element_by_XX(都会自动调用全局等待设置的时间)
driver.get('https://ke.qq.com')
driver.find_element_by_id('js_login').click()
driver.close() # 关闭当前的窗口
driver.quite() # 关闭浏览器则关闭了chromedriver3.3 三大等待之显性等待
- 明确的条件:(元素可见,窗口存在…) 等待+条件
- 引入相应的库,明确等到某一条件满足后,再去执行下一步操作。程序每隔XX秒看一眼,
如果条件成立了,则执行下一步,否则继续等待,直到超过设置的最长时间,则抛出TimeoutException - WebDriverWait类:显性等待类
WebDriverWait(driver,等待时长,轮询周期).until()/until_not()(直到条件成立..才/直到条件不成立….才) - expected_conditions模块:提供一系列期望发生的条件
presence_of_element_located: 元素存在
visibility_of_element_located: 元素可见
element_to_be_clickable: 元素可点击
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16# 方法一
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
# 元素存在: 在HTML里面存在,能找到,可以定位到
# 元素可见: 存在并且可见,看得见大小,宽高,可见才可以操作
# 元素可用: 前提:可见(只读,不可点击都不可用)可见之后,才有可用的可能性
# 等待表达式:lacator=(定位类型定位表达式)
locator = (By.ID ,'TANGRAM__PSP_10__footerULoginBtn')
# 条件:EC.visibility_of_element_located(locator)
# 等待元素可见
WebDriverWait(driver,30,1).until(EC.visibility_of_element_located(locator))
辅助---0.5秒 提高速度
sleep(0.5)
# 点击元素
driver.find_element_by_id("TANGRAM__PSP_10__footerULoginBtn").click()1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# 方法二
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium import webdriver
driver = webdriver.Chrome() # 浏览器会话开启
driver.implicitly_wait(20) # 设置全局等待时间
driver.get('https://www.baidu.com') # 加载静态界面
driver.find_element_by_id('kw').clear() # 清除输入文本框
driver.find_element_by_id('kw').send_keys('柠檬班')
driver.find_element_by_id('su').click()
# 等待(有个小技巧)
locator = (By.XPATH,"//a[text()='_腾讯课堂']")
WebDriverWait(driver,30,1).until(EC.visibility_of_element_located(locator))
sleep(0.5) # 辅助 提高代码速度
driver.find_element(*locator).click() # 解包 小技巧,减少代码的重复性1
2
3
4
5
6
7
8
9
10封装操作等待的方法
def common_wait(element):
locator = (By.XPATH,element)
try:
WebDriverWait(driver,30,1).until(EC.visibility_of_element_located(locator))
except TimeoutException:
print('没有找到该元素!')
else:
# 没有异常,走else下面的代码
return driver.find_element(*locator)
详解三大切换
4.1 三大切换之iframe
iframe:frame切换有2种方法- driver.switch_to.frame(frame_reference)
frame_reference的值有3种:- iframe的下标(在当前页面中第几个iframe)
- iframe的name的属性
- iframe的WebElement对象
- frame_to_be_available_and_switch_to_it(frame_reference)
判断iframe是否可用,并且自动切换到iframe新的html页面中
frame_reference取值同方法一: - 退出iframe回到默认的页面
driver.switch_to.default_content() - 返回到上一个父iframe页面
driver.switch_to.parent_frame()1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16第一种方法:
操作使用账号密码登录腾讯课堂
driver.switch_to.frame(下标索引)
driver.switch_to.frame('name属性值')
driver.switch_to.frame(WebElement对象)
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://ke.qq.com')
sleep(2)
common_wait("//a[@id='js_login']",driver).click()
common_wait("//a[text()='QQ登录']",driver).click()
driver.switch_to.frame(4) # 方法1.1
driver.switch_to.frame("login_frame_qq") # 方法1.2 --->常用
driver.switch_to.frame(driver.find_element_by_xpath('//iframe[@name="login_frame_qq"]')) # 方法1.3
# 进入了iframe里面的html页面,主页面了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15第二种方法:iframe可用然后切进iframe 等待+切换
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://ke.qq.com')
sleep(2)
common_wait("//a[@id='js_login']",driver).click()
common_wait("//a[text()='QQ登录']",driver).click()
WebDriverWait(driver,20).until(EC.frame_to_be_available_and_switch_to_it(4)) # 方法2.1
WebDriverWait(driver,20).until(EC.frame_to_be_available_and_switch_to_it(login_frame_qq)) # 方法2.2---》常用
WebDriverWait(driver,20).until(EC.frame_to_be_available_and_switch_to_it(driver.find_element_by_xpath('//iframe[@name="login_frame_qq"]'))) # 方法2.3
# 进入了iframe里面的html页面,主页面了。4.2 三大切换之window
window:窗口切换 有2种方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35第一种方法:
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
driver = webdriver.Chrome()
driver.implicitly_wait(20)
driver.get('https://www.baidu.com') # 加载静态界面
driver.find_element_by_id('kw').clear() # 清空文本输入框
driver.find_element_by_id('kw').send_keys('柠檬班') # 输入柠檬班
driver.find_element_by_id('su').click() # 点击百度一下的按钮
# 等待
locator = (By.XPATH,"//a[text()='_腾讯课堂']")
WebDriverWait(driver,20,1).until(EC.visibility_of_element_located(locator))
driver.find_element(*locator)
# 点击柠檬班_腾讯课堂
打开新的窗口
1. 获取所有的窗口(handle:句柄,唯一的id值)
handles = driver.window_handles # 按照窗口出现的顺序,最后一个就是最近打开的窗口
print('所有的句柄是:{}'.format(handles)) # 得到的是列表
current_handle = driver.current_window_handle
print('当前的窗口的句柄是:{}'.format(current_handle))
2. 切换新的窗口,点击课程
driver.switch_to.window(handles[-1])
print('切换之后的窗口为:{}'.format(driver.current_window_handle))
# 在新的窗口中,点击课程
# 页面之中,等待
locator = (By.XPATH,"//section[@class='section-main']//h2[contains(text(),'课程')]")
WebDriverWait(driver,20,1).until(EC.visibility_of_element_located(locator))
driver.find_element(*locator).click()1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34方法二:
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
driver = webdriver.Chrome()
driver.implicitly_wait(20)
driver.get('https://www.baidu.com') # 加载静态界面
driver.find_element_by_id('kw').clear() # 清空文本输入框
driver.find_element_by_id('kw').send_keys('柠檬班') # 输入柠檬班
driver.find_element_by_id('su').click() # 点击百度一下的按钮
# 等待
locator = (By.XPATH,"//a[text()='_腾讯课堂']")
WebDriverWait(driver,20,1).until(EC.visibility_of_element_located(locator))
# 点击柠檬班_腾讯课堂
# step1:获取窗口数
handles = driver.window_handles # 只有一个窗口(因为上一步没有点击操作)
# step2: 执行打开新窗口的操作
driver.find_element(*locator).click() # 本操作带来了新的窗口---2个
# step3: 确认新的窗口出现了,再去操作它,等待新窗口出现(只是确认啦新窗口,没有切换)
WebDriverWait(driver,20,1).until(EC.new_window_is_opened(handles)) # 确认新窗口的出现
# step4: 再次获取,窗口的handles
handles = driver.www
# step5: 切换到新窗口
driver.switch_to.window(handles[-1])
# 在新的窗口中,点击课程
# 页面之中,等待
locator = (By.XPATH,"//section[@class='section-main']//h2[contains(text(),'课程')]")
WebDriverWait(driver,20,1).until(EC.visibility_of_element_located(locator))
driver.find_element(*locator)- driver.switch_to.frame(frame_reference)
4.3 三大切换之alert
弹出框有2种:
1. 页面弹出框---》html页面元素 DOM
1. 执行触发操作后,等待弹出框出现
2. 再定位弹出框的元素并操作
2. alert弹出框---Alert类--html页面上无法定位(不是html元素)
切换--》接收 switch_to.alert--》alert是属性
1. 浏览器弹出框,使用switch_to.alert方法切换到浏览器弹出框(driver.switch_to.alert)
2. alert提供一系列操作方法:
1. click()---->点击操作
2. accept()---->点击确定按钮
3. dismiss()---->点击取消按钮
4. text()---->获取弹出框里面的内容
5. send_keys()---->向弹出框输入文本
1 | from selenium import webdriver |
图形验证码:
1. 主动屏蔽
2. 找开发 配置万能验证码
3. 验证码一般会入库,可以直接去数据库查询入库的验证码,然后输入即可
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 筱茗辰!