python3+selenium4實現(xiàn)切換窗口與iframe的方法
在自動化測試過程中,有時后會遇到元素定位方式?jīng)]有問題,但是依舊拋出無法找到元素的異常的問題,通常情況下,如果元素定位沒有問題,但還是無法找到元素,則可能是由于當(dāng)前焦點不在指定頁面或iframe導(dǎo)致的,以下將對兩種情況分別進(jìn)行說明
1、切換窗口
比如我們現(xiàn)在有這樣一個需求,進(jìn)入百度首頁后,點擊新聞,然后在新聞頁面的搜索框輸入selenium
而使用selenium要如何實現(xiàn)呢,在對selenium不是很熟悉的情況下,僅僅學(xué)習(xí)了之前的內(nèi)容,寫出的代碼就可能會拋出找不到貼吧搜索輸入框元素異常,示例代碼如下
from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Edge() driver.get("https://www.baidu.com/") driver.find_element(By.LINK_TEXT, '新聞').click() # 點擊新聞 driver.find_element(By.ID, 'ww').send_keys('selenium') # 在新聞首頁搜索框輸入selenium driver.quit()
代碼看起來沒什么問題,打開百度首頁,點擊貼吧,然后在貼吧登錄頁面點擊立即注冊,元素定位也沒錯,但是執(zhí)行就會拋出異常,無法找到貼吧的輸入框元素
造成此錯誤的原因是因為點擊新聞之后,又打開了一個新的窗口,此時打開的窗口有百度首頁和新聞頁,而selenium不知道我們需不需要切換窗口,所以不會自動給我們切換窗口,需要手動進(jìn)行窗口的切換
而要實現(xiàn)窗口的切換,則需要用到獲取瀏覽器句柄以及窗口切換的方法
1.1、獲取句柄
句柄是當(dāng)前瀏覽器窗口或選項卡的一個類似id一樣的唯一標(biāo)識,可以用來判斷當(dāng)前窗口或選項卡是否在指定的窗口,獲取句柄的方法如下:
獲取當(dāng)前頁面句柄 driver.current_window_handle 獲取當(dāng)前所有存在的窗口句柄,多個句柄以列表方式存儲 driver.window_handles
通常的,我們只需要使用當(dāng)前窗口句柄與所有窗口句柄列表進(jìn)行對比,然后使用窗口切換的方法,就可以完成窗口的切換
1.2、切換窗口
要完成窗口切換,需要使用方法switch_to.window(),完成新聞頁輸入selenium操作完整成功的示例代碼如下:
from selenium import webdriver from selenium.webdriver.common.by import By import time driver = webdriver.Edge() driver.get("https://www.baidu.com/") driver.find_element(By.LINK_TEXT, '新聞').click() # 點擊新聞 handle = driver.current_window_handle # 獲取當(dāng)前窗口句柄 handles = driver.window_handles # 獲取所有窗口句柄 for window_handle in handles: # 循環(huán)比較句柄 if window_handle != handle: # 如果窗口句柄與當(dāng)前窗口句柄不一致,則切換到該窗口 driver.switch_to.window(window_handle) driver.find_element(By.ID, 'ww').send_keys('selenium') # 在新聞首頁搜索框輸入selenium time.sleep(2) driver.quit()
以上代碼只適用于兩個窗口的切換,如果同時打開更多窗口,使用上述代碼只能切換到列表最后一個非當(dāng)前窗口,那存在多個窗口時需要如何準(zhǔn)確的切換到指定的窗口呢,其實只需要追加一層判斷即可,示例如下:
from selenium import webdriver from selenium.webdriver.common.by import By import time driver = webdriver.Edge() driver.get("https://www.baidu.com/") driver.find_element(By.LINK_TEXT, '新聞').click() # 點擊新聞 handle = driver.current_window_handle # 獲取當(dāng)前窗口句柄 handles = driver.window_handles # 獲取所有窗口句柄 for window_handle in handles: # 循環(huán)比較句柄 if window_handle != handle: # 如果窗口句柄與當(dāng)前窗口句柄不一致,則切換到該窗口 driver.switch_to.window(window_handle) if driver.title == '百度新聞——海量中文資訊平臺': # 如果切換后的窗口的title與指定的一致,結(jié)束循環(huán) break driver.find_element(By.ID, 'ww').send_keys('selenium') # 在新聞首頁搜索框輸入selenium time.sleep(2) driver.quit()
上述代碼中添加了一層判斷切換后的窗口title是否與預(yù)期一致,如果一致則跳出循環(huán)以保證多窗口切換時能夠準(zhǔn)確的切換到預(yù)期的窗口就停止切換
1.3、關(guān)閉窗口并切換回原窗口
在切換到指定窗口完成測試后,如果我們需要關(guān)閉此窗口并切換到原來的窗口,示例代碼如下:
from selenium import webdriver from selenium.webdriver.common.by import By import time driver = webdriver.Edge() driver.get("https://www.baidu.com/") driver.find_element(By.LINK_TEXT, '新聞').click() # 點擊新聞 handle = driver.current_window_handle # 獲取當(dāng)前窗口句柄 handles = driver.window_handles # 獲取所有窗口句柄 for window_handle in handles: # 循環(huán)比較句柄 if window_handle != handle: # 如果窗口句柄與當(dāng)前窗口句柄不一致,則切換到該窗口 driver.switch_to.window(window_handle) if driver.title == '百度新聞——海量中文資訊平臺': # 如果切換后的窗口的title與指定的一致,結(jié)束循環(huán) break driver.find_element(By.ID, 'ww').send_keys('selenium') # 在新聞首頁搜索框輸入selenium driver.close() # 關(guān)閉當(dāng)前新聞窗口 driver.switch_to.window(handle) # 切換回原窗口,即百度首頁 driver.find_element(By.ID, 'kw').send_keys('selenium') # 百度首頁輸入框輸入selenium time.sleep(2) driver.quit()
需要注意的是,close()方法只是關(guān)閉當(dāng)前所在窗口,但驅(qū)動的瀏覽器依舊處于等待執(zhí)行狀態(tài),而quit()則會退出當(dāng)前會話,無論打開了多少個窗口,均會被一次性關(guān)閉,且瀏覽器不再接受新的操作命令
2、切換iframe
除了打開多個窗口會導(dǎo)致無法找到元素之外,如果元素包含在iframe中,也會導(dǎo)致無法找到元素,比如現(xiàn)有如下元素:
<html> <iframe src="a.html" id="frame0" name="frame1"> <input id="kw" / > </iframe> </html>
此時id為kw的input標(biāo)簽元素處于iframe中,要定位此元素,若直接使用
driver.find_element(By.ID, 'kw')
也會拋出無法找到元素的異常,那么如何實現(xiàn)frame的切換,從而精準(zhǔn)定位到元素呢
2.1、切換到iframe中
selenium提供了switch_to.frame()方法用于實現(xiàn)frame的切換,此方法接收id、name、index以及selenium的WebElement對象用來實現(xiàn)切換,比如上述的代碼中,要切換到iframe中,則可以使用以下代碼實現(xiàn):
from selenium import webdriver driver = webdriver.Edge() driver.switch_to.frame('frame0') # 通過id切換iframe # driver.switch_to.frame('frame1') # 通過name切換iframe # driver.switch_to.frame(0) # 通過index切換iframe,0代表第一個 # driver.switch_to.frame(driver.find_element_by_tag_name("iframe")) # 通過WebElement對象切換iframe
一般情況下,通過id或name即可解決大部分iframe切換的問題,如果沒有這兩個屬性,再考慮使用index以及WebElement對象來實現(xiàn)
2.2、從frame中切換到主界面
在測試過程中,我們不僅會從主界面切換到iframe中,當(dāng)操作完frame中的元素后,經(jīng)常需要重新切換到主界面進(jìn)行其他操作,切換回主頁面使用方法如下:
driver.switch_to.default_content()
2.3、嵌套多層iframe的切換
有時候我們會遇到嵌套多層frame的情況,如下所示
<html> <iframe src="a.html" id="frame1"> <iframe src="b.html" id="frame2" > <input id="kw" / > </iframe> </iframe> </html>
多層嵌套的情況下,如果要從主界面切換到第二層iframe,則需要一層一層的切換進(jìn)去,即先切換到frame1,再切換到frame2,而不是直接切換進(jìn)入frame2
driver.switch_to.frame("frame1") driver.switch_to.frame("frame2")
selenium還提供了一個切換到父frame的方法,比如我們切換到frame2之后,要想切換到frame1操作,則不需要先切回主界面再切換到frame,而是使用如下方法:
driver.switch_to.parent_frame()
需要注意的是,如果當(dāng)前已經(jīng)是主頁面,則使用此方法無效
靈活使用以上方法,則可輕松應(yīng)對iframe的切換與窗口切換的問題,從此告別定位不到元素的苦惱
到此這篇關(guān)于python3+selenium4實現(xiàn)切換窗口與iframe的方法的文章就介紹到這了,更多相關(guān)python3 selenium4切換窗口與iframe內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python中scrapy處理項目數(shù)據(jù)的實例分析
在本篇文章里小編給大家整理了關(guān)于python中scrapy處理項目數(shù)據(jù)的實例分析內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。2020-11-11關(guān)于numpy.polyfit()與Stats.linregress()方法最小二乘近似擬合斜率對比
這篇文章主要介紹了關(guān)于numpy.polyfit()與Stats.linregress()方法最小二乘近似擬合斜率對比,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04詳解如何在cmd命令窗口中搭建簡單的python開發(fā)環(huán)境
這篇文章主要介紹了詳解如何在cmd命令窗口中搭建簡單的python開發(fā)環(huán)境,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08windows下添加Python環(huán)境變量的方法匯總
默認(rèn)情況下,在windows下安裝python之后,系統(tǒng)并不會自動添加相應(yīng)的環(huán)境變量。此時不能在命令行直接使用python命令。今天我們就來看下,如何簡單快捷的在windows下添加Python環(huán)境變量2018-05-05Django利用Channels+websocket開發(fā)聊天室完整案例
Channels是Django團(tuán)隊研發(fā)的一個給Django提供websocket支持的框架,使用它我們可以輕松開發(fā)需要長鏈接的實時通訊應(yīng)用,下面這篇文章主要給大家介紹了關(guān)于Django利用Channels+websocket開發(fā)聊天室的相關(guān)資料,需要的朋友可以參考下2023-06-06