一、handle窗口切換
當點擊某個元素后,會重新生成一個新的頁簽,但此時我們的操作仍然在原先的窗口當中,如果要在新的窗口繼續操作元素,那么就要用到handle窗口切換的方法。
常用方法:
window_handles:獲取當前打開的所有窗口句柄,返回類型為一個列表。
current_window_handle:獲取當前窗口的句柄。
switch_to.window(handle_path):切換窗口,handle_path參數代表的是一個窗口句柄。
當操作某個元素后需要等待新的元素出現,我們用到了顯性等待,EC給了我們一個方法為visibility_of_element_located(),表示元素可見,那么在handle窗口切換時也涉及到等待,那就是等待新的窗口打開,我將用一般方法和新的方法來展示,具體用法如下:
方法一(使用time.sleep()強制等待):
import time 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.get("http://www.baidu.com") driver.maximize_window() driver.find_element_by_id("kw").send_keys("python") driver.find_element_by_id("su").click() loc = (By.XPATH, "//a[text()=' 基礎教程 | 菜鳥教程']") WebDriverWait(driver, 20).until(EC.visibility_of_element_located(loc)) driver.find_element(*loc).click() # 點擊后新的窗口出現 # 切換到新的窗口,在新窗口去操作元素 time.sleep(1) # 強制等待1秒 # 1、獲取當前打開的所有窗口。 --- 窗口列表。handles wins = driver.window_handles print(wins) # 打印打前窗口的句柄 print(driver.current_window_handle) # 2、切換的語句 ,切換到你想操作元素所在的窗口。進入到了新的html頁面 - 新的窗口 wins[-1] driver.switch_to.window(wins[-1]) # 3、在新的頁面當中,找元素,並操作 loc = (By.XPATH, "//ul[@class='pc-nav']//a[text()='首頁']") WebDriverWait(driver, 20).until(EC.visibility_of_element_located(loc)) driver.find_element(*loc).click()
方法二(使用騷操作EC.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 driver = webdriver.Chrome() driver.get("http://www.baidu.com") driver.maximize_window() driver.find_element_by_id("kw").send_keys("python") driver.find_element_by_id("su").click() loc = (By.XPATH, "//a[text()=' 基礎教程 | 菜鳥教程']") WebDriverWait(driver, 20).until(EC.visibility_of_element_located(loc)) cur_handles = driver.window_handles # 點擊操作之前的窗口總數為1 driver.find_element(*loc).click() # 點擊后新的窗口出現 # 等待一下,窗口總數會變成2個 # 切換到新的窗口,在新窗口去操作元素。 # Ec條件 -- 等待新窗口出現 WebDriverWait(driver, 20).until(EC.new_window_is_opened(cur_handles)) # 更穩定的窗口等待 # 再次獲取窗口列表 。總數為2 # 1、獲取當前打開的所有窗口。 --- 窗口列表。handles wins = driver.window_handles print(wins) # 打印打前窗口的句柄 print(driver.current_window_handle) # 2、切換的語句,切換到你想操作元素所在的窗口。進入到了新的html頁面 - 新的窗口 wins[-1] driver.switch_to.window(wins[-1]) # 3、在新的頁面當中,找元素,並操作。 loc = (By.XPATH, "//ul[@class='pc-nav']//a[text()='首頁']") WebDriverWait(driver, 20).until(EC.visibility_of_element_located(loc)) driver.find_element(*loc).click()
二、iframe切換
iframe表示在主html上嵌入的子html頁面如下圖所示:
當我們要在新的html頁面操作元素,就要切換到新的html頁面后才能進行接下來的操作,常用方法如下:
switch_to.frame(path):切換到新的html頁面,path支持下標、name、WebElement對象三種參數
switch_to.default_content():切換到主html頁面
switch_to.parent_frame():切換到上一層html頁面(父頁面)
在iframe切換中也有等待,除了使用time.sleep()方法外,EC給了我們一個方法為frame_to_be_available_and_switch_to_it(),表示iframe有效並切換到iframe當中,它支持下標、name、WebElement對象以及元組四種方法傳參,兩種方法如下:
方法一(使用time.sleep()強制等待):
import time 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.get("https://www.baidu.com") driver.maximize_window() driver.find_element_by_id("kw").send_keys("qq空間") driver.find_element_by_id("su").click() loc = (By.XPATH, "//a[text()='官網']/preceding-sibling::a[text()='-分享生活,留住感動']") WebDriverWait(driver, 20).until(EC.visibility_of_element_located(loc)) cur_handles = driver.window_handles # 點擊操作之前的窗口總數為1 driver.find_element(*loc).click() # 點擊后新的窗口出現 # 等待一下,窗口總數會變成2個 # 切換到新的窗口,在新窗口去操作元素。 # Ec條件 -- 等待新窗口出現 WebDriverWait(driver, 20).until(EC.new_window_is_opened(cur_handles)) # 更穩定的窗口等待 # 再次獲取窗口列表 。總數為2 # 獲取當前打開的所有窗口。 --- 窗口列表。handles wins = driver.window_handles # 切換的語句,切換到你想操作元素所在的窗口。進入到了新的html頁面 - 新的窗口 wins[-1] driver.switch_to.window(wins[-1]) # 切換iframe driver.switch_to.frame("login_frame") time.sleep(1) # 強制等待1秒 driver.find_element_by_xpath("//div[@id='bottom_web']//a[text()='注冊新帳號']").click()
方法二(使用騷操作EC.frame_to_be_available_and_switch_to_it()方法):
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.get("https://www.baidu.com") driver.maximize_window() driver.find_element_by_id("kw").send_keys("qq空間") driver.find_element_by_id("su").click() loc = (By.XPATH, "//a[text()='官網']/preceding-sibling::a[text()='-分享生活,留住感動']") WebDriverWait(driver, 20).until(EC.visibility_of_element_located(loc)) cur_handles = driver.window_handles # 點擊操作之前的窗口總數為1 driver.find_element(*loc).click() # 點擊后新的窗口出現 # 等待一下,窗口總數會變成2個 # 切換到新的窗口,在新窗口去操作元素。 # Ec條件 -- 等待新窗口出現 WebDriverWait(driver, 20).until(EC.new_window_is_opened(cur_handles)) # 更穩定的窗口等待 # 再次獲取窗口列表 。總數為2 # 獲取當前打開的所有窗口。 --- 窗口列表。handles wins = driver.window_handles # 切換的語句,切換到你想操作元素所在的窗口。進入到了新的html頁面 - 新的窗口 wins[-1] driver.switch_to.window(wins[-1]) # EC條件 - 等待iframe有效並切換到iframe當中 WebDriverWait(driver, 20).until( EC.frame_to_be_available_and_switch_to_it((By.XPATH, '//iframe[@id="login_frame"]'))) driver.find_element_by_xpath("//div[@id='bottom_web']//a[text()='注冊新帳號']").click()
三、alert彈框切換
如何區分是alert彈框呢?一個簡單的方法就是無法使用元素定位的彈框,並且需要優先處理后才能操作后面的元素,常用方法如下:
switch_to.alert:切換到alert彈框
accept():確定
dismiss():取消
send_keys(keysToSend) :輸入文本,keysToSend表示輸入的文本內容字符串
text():獲取彈出框里面的內容
在EC里面也給alert彈框設定了一個方法,alert_is_present()方法表示等待alert彈框出現並切換到alert彈框中
方法一(常規做法):
from selenium import webdriver driver = webdriver.Chrome() driver.maximize_window() driver.get("http://XXXX") # 做一個操作,導致alert框出現 driver.find_element_by_id("idxxx").click() # 切換到alert彈框 alert = driver.switch_to.alert # 獲取alert的文本內容 print(alert.text) # 點擊確定,關閉彈框 alert.accept()
方法二(使用騷操作EC.alert_is_present()方法):
from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Chrome() driver.maximize_window() driver.get("http://XXXX") # 做一個操作,導致alert框出現 driver.find_element_by_id("idxxx").click() # EC條件 -- 等待alert彈框出現,並切換到alert當中 alert = WebDriverWait(driver, 10).until(EC.alert_is_present()) # 獲取alert的文本內容 print(alert.text) # 點擊確定,關閉彈框 alert.accept()