我們在做UI自動化時,不得不會遇到一些窗口跳轉與彈框,在這種的時候如果不進行切換的話,繼續執行腳本必然會報錯,所以我們就需要用到切換窗口的方法。
selenium中主要是三種窗口
- Windows窗口
- iframe窗口
- alert窗口
1、Windows窗口
這類窗口也就是我們常說的句柄,句柄的切換是有必要的,我們自己手動在網頁上從操作的話,產生新的句柄時瀏覽器會自動的幫我們跳轉到最新的句柄處,但是我們在做UI自動化的時候,代碼並不會幫我們自動的切換到最新的句柄,需要我們使用代碼去進行切換
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.get("http://www.baidu.com") driver.find_element(By.ID, "kw").send_keys("騰訊課堂") driver.find_element(By.ID, "kw").send_keys(Keys.ENTER) loc = (By.XPATH, '//div[@id="1"]//h3[@class="t"]//em') WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located(loc)) driver.find_element(*loc).click()
以上的代碼腳本,就會產生一個新的Windows窗口,如圖:
我們如果直接去執行下一步操作的話,會報錯的,所以我們需要先跳轉到新的窗口才行
需要加上以下代碼:
windows = driver.window_handles # 獲取該會話所有的句柄 driver.switch_to.window(windows[-1]) # 跳轉到最新的句柄
然后我們就可以在這個窗口里面進行新的操作了
2、iframe窗口
iframe窗口是嵌套在我們整個HTML里面的一個HTML的頁面,我們如果要對這個iframe中的元素進行操作,那么久必須要先跳轉至這個iframe窗口才可以進行該操作,不然就會導致報錯
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.get("http://www.baidu.com") driver.find_element(By.ID, "kw").send_keys("騰訊課堂") driver.find_element(By.ID, "kw").send_keys(Keys.ENTER) loc = (By.XPATH, '//div[@id="1"]//h3[@class="t"]//em') WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located(loc)) driver.find_element(*loc).click() windows = driver.window_handles # 獲取該會話所有的句柄 driver.switch_to.window(windows[-1]) # 跳轉到最新的句柄 first_login = (By.XPATH, '//a[@class="mod-header__link-login js-login-op"]') # 騰訊課堂首頁登錄按鈕 WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located(first_login)) # 顯性等待到登錄按鈕加載出來,沒隔0.5檢查一共10秒 # 顯性等待首頁中的登錄按鈕是否存在 WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located(first_login)) # 點擊登錄按鈕 driver.find_element(*first_login).click() # 顯性等待用qq登錄是否存在 WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located( (By.XPATH, '//a[@class="js-btns-enter btns-enter btns-enter-qq"]'))) driver.find_element(By.XPATH, '//a[@class="js-btns-enter btns-enter btns-enter-qq"]').click() # 顯性等待賬號密碼登錄 WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located( (By.XPATH, '//a[@id="switcher_plogin"]') )) driver.find_element(By.XPATH, '//a[@id="switcher_plogin"]').click()
以上代碼,執行的話就會報錯,這是因為啥呢?
仔細研究下,發現是因為我們最后查找的元素是屬於iframe窗口的
所以需要我們在查找此元素之前就要跳轉到iframe窗口才可以找到該元素,也就不會報錯了,請看以下:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.get("http://www.baidu.com") driver.find_element(By.ID, "kw").send_keys("騰訊課堂") driver.find_element(By.ID, "kw").send_keys(Keys.ENTER) loc = (By.XPATH, '//div[@id="1"]//h3[@class="t"]//em') WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located(loc)) driver.find_element(*loc).click() windows = driver.window_handles # 獲取該會話所有的句柄 driver.switch_to.window(windows[-1]) # 跳轉到最新的句柄 first_login = (By.XPATH, '//a[@class="mod-header__link-login js-login-op"]') # 騰訊課堂首頁登錄按鈕 WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located(first_login)) # 顯性等待到登錄按鈕加載出來,沒隔0.5檢查一共10秒 # 顯性等待首頁中的登錄按鈕是否存在 WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located(first_login)) # 點擊登錄按鈕 driver.find_element(*first_login).click() # 顯性等待用qq登錄是否存在 WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located( (By.XPATH, '//a[@class="js-btns-enter btns-enter btns-enter-qq"]'))) driver.find_element(By.XPATH, '//a[@class="js-btns-enter btns-enter btns-enter-qq"]').click() # 跳轉到iframe窗口 driver.switch_to.frame('login_frame_qq') # 顯性等待賬號密碼登錄 WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located( (By.XPATH, '//a[@id="switcher_plogin"]') )) driver.find_element(By.XPATH, '//a[@id="switcher_plogin"]').click()
上面紅色加粗代碼就是我們加上的代碼,參數的話可以有多種格式,我這里傳遞的參數時iframe的name值,有人可能會問:如果這個name值在這個HTML里面有多個name值呢?那我該咋辦?
其實driver.switch_to.frame(value)中這個value值不光可以填寫iframe的name值,還可以填寫整個HTML中所有iframe的索引值(比如:整個HTML有5個iframe,我可以輸入0-4的索引值來選擇我需要的iframe),還可以是這個元素對象(可以通過該iframe的其他屬性:比如id、class等元素定位方式來查找)
在我們對這個iframe操作結束后,我們還是需要回到默認的頁面去的,這個時候selenium也給我提供了一步到位的操作
driver.switch_to.default_content()
這行代碼就可以回到我們本次會話的最開始的頁面
3、alert窗口
alert窗口就是Windows窗口彈出的提示框,在有這個提示框的作用下,我們是不能做其他的任何操作的,必須要將這個alert彈框給刪除掉才可以進行其他操作
selenium中提供了操作
driver.switch_to.alert.accept() # 確定操作 driver.switch_to.alert.dismiss() # 取消操作 driver.switch_to.alert.send_keys("") # alert彈框輸入文本 driver.switch_to.alert.text() # 獲取alert的文本內容
今天主要總結的是三大彈框操作,總結的不到位的歡迎各位進行評論交流哈,,