前言
在selenium的web自动化当中会遇到一些窗口跳转或者对话框的弹出。在selenium中,提供了三种切换:Windows窗口切换,iframe切换,alert弹窗切换。
Windows窗口切换
直接举例子,比如我们在百度搜索“腾讯课堂”,在搜索结果中点击,会弹出一个新的窗口,那么如果我要在新的窗口操作,那么我们就需要进行切换,切换后在新的界面点击登录按钮: 具体实现代码:
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
chrome_driver = webdriver.Chrome()
chrome_driver.maximize_window()
chrome_driver.get("http://www.baidu.com")
chrome_driver.find_element_by_xpath('//*[@id="kw"]').send_keys("腾讯课堂")
chrome_driver.find_element_by_id('su').click()
loc = (By.XPATH, '//*[@id="3001"]/div/div[1]/div/div/h3/div/a[1]')
WebDriverWait(chrome_driver, 30, 0.2).until(EC.visibility_of_element_located(loc))
chrome_driver.find_element(*loc).click()
time.sleep(1)
wins = chrome_driver.window_handles
print(wins)
print(chrome_driver.current_window_handle)
chrome_driver.switch_to.window(wins[-1])
loc1 = (By.XPATH, '//*[@id="mgr_nav_login"]')
WebDriverWait(chrome_driver, 30).until(EC.visibility_of_element_located(loc1))
chrome_driver.find_element(*loc1).click()
实现效果: 切换window窗口,除了上面的switch_to.window,还有expected_conditions类提供的一种方法new_window_is_opened。 比如上面的代码,可以写为:
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
chrome_driver = webdriver.Chrome()
chrome_driver.maximize_window()
chrome_driver.get("http://www.baidu.com")
chrome_driver.find_element_by_xpath('//*[@id="kw"]').send_keys("腾讯课堂")
chrome_driver.find_element_by_id('su').click()
loc = (By.XPATH, '//*[@id="3001"]/div/div[1]/div/div/h3/div/a[1]')
WebDriverWait(chrome_driver, 30, 0.2).until(EC.visibility_of_element_located(loc))
cu_windows = chrome_driver.window_handles
chrome_driver.find_element(*loc).click()
EC.new_window_is_opened(cu_windows)
loc1 = (By.XPATH, '//*[@id="mgr_nav_login"]')
WebDriverWait(chrome_driver, 30).until(EC.visibility_of_element_located(loc1))
chrome_driver.find_element(*loc1).click()
iframe切换
iframe窗口是嵌套在我们整个HTML里面的一个HTML的页面,我们如果要对这个iframe中的元素进行操作,那么就必须要先切换这个iframe窗口才可以进行操作。 比如我们下面网页,点击登录界面的注册新账号,我们在开发管理工具中,可以看到,这个按钮在iframe上,要点击这个按钮,首先要切换到它所在的frame上才行,否则会报错: 实现代码:
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.Chrome()
driver.maximize_window()
driver.get("https://connect.qq.com/")
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_loc = (By.XPATH, '//*[@id="login_frame"]')
WebDriverWait(driver, 30).until(EC.presence_of_element_located(frame_loc))
driver.switch_to.frame(driver.find_element_by_xpath('//*[@id="login_frame"]'))
driver.find_element_by_xpath('//div[@id="bottom_qlogin"]/a[text()="注册新帐号"]').click()
效果: 下面这一句代码,切换frame时,传入的时webElement对象,其实还可以传入下标或者name属性的值:
driver.switch_to.frame(driver.find_element_by_xpath('//*[@id="login_frame"]'))
比如:
driver.switch_to.frame(0)
driver.switch_to.frame("login_frame")
当在frame上操作完毕后,如果要返回到原来的界面或者主界面,要进行切换。 切换到主界面:
chrome_driver.switch_to.default_content()
切换到父级的frame:
chrome_driver.switch_to.parent_frame()
其实,frame切换,除了上面说的driver.switch_to.frame的方式,还有一种是由expected_conditions提供的frame_to_be_available_and_switch_to_it方法。 比如上面的代码中,这两句代码:
WebDriverWait(driver, 30).until(EC.presence_of_element_located(frame_loc))
driver.switch_to.frame(driver.find_element_by_xpath('//*[@id="login_frame"]'))
可以用下面这句代码进行替换,效果是一样的:
WebDriverWait(driver, 30).until(EC.frame_to_be_available_and_switch_to_it(frame_loc))
替换后代码:
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.Chrome()
driver.maximize_window()
driver.get("https://connect.qq.com/")
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_loc = (By.XPATH, '//*[@id="login_frame"]')
WebDriverWait(driver, 30).until(EC.frame_to_be_available_and_switch_to_it(frame_loc))
driver.find_element_by_xpath('//div[@id="bottom_qlogin"]/a[text()="注册新帐号"]').click()
alert弹窗切换
alert窗口就是js提示框,它不属于web界面,所以,在有这个提示框的作用下,我们是无法继续web操作的,必须先处理掉js弹窗,才可以继续。 Alert类提供了四个方法来处理弹窗:
driver.switch_to.alert.accept()
driver.switch_to.alert.dismiss()
driver.switch_to.alert.send_keys("")
driver.switch_to.alert.text()
同上面两种切换一样,alert切换时,expected_conditions类也提供了一个切换方法alert_is_present:
alert = WebDriverWait(driver, 10).until(EC.alert_is_present())
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
driver = webdriver.Chrome()
driver.get("my.html")
alert = WebDriverWait(driver, 10).until(EC.alert_is_present())
alert.accept()
alert.dismiss()
alert.send_keys()
alert.text()
|