關(guān)鍵字:python3.6 selenium frame Chrome
selenium自動化測試,frame標(biāo)簽有的時候很令人煩惱。frame類似于在原有主html的基礎(chǔ)上又嵌套一個html,而且嵌套的html是獨(dú)立使用,互不影響。frame的方案經(jīng)常發(fā)生在網(wǎng)頁中的導(dǎo)航赎瞎。
如下:
<!DOCTYPE html>
<html lang="en">
<head>
<title>FrameTest</title>
</head>
<body>
<iframe src="a.html" id="frame1" name="myframe"></iframe>
</body>
</html>
以上的主html里面嵌套了一個iframe標(biāo)簽,也就是里面還有一個a.html颊咬。如果我們需要定位的元素在a.html里面务甥,就需要切換到iframe標(biāo)簽后再去定位。
frame相關(guān)的標(biāo)簽有frameset,frame,iframe三種喳篇。frameset不需要切換敞临,frame和iframe需要切換。切換的方式是swith_to.frame(reference)麸澜。
reference可以傳入id挺尿、name、index以及selenium的WebElement對象炊邦。
case:從路由器配置頁面抓取到wan口的ip地址编矾。
1)登錄
Chrome F12,查看元素后馁害,可以看到當(dāng)前用戶名輸入框input標(biāo)簽窄俏,有一個name屬性account,同時它的父節(jié)點(diǎn)有一個id屬性是dl_margin。
css選擇器語法是:#dl_margin input[name='account']
密碼輸入框處理同用戶輸入框碘菜,css選擇器語法是:#dl_margin input[name='password']
登錄按鈕直接根據(jù)id屬性選擇:longin_button
2)frame切換
登錄后首頁凹蜈,點(diǎn)擊基本信息后,顯示當(dāng)前wan口的ip地址
定位到基本信息后忍啸,注意到前面的父節(jié)點(diǎn)有一個html
切換過去之后仰坦,的確有一個iframe標(biāo)簽。
但是就這么結(jié)束了嗎计雌?沒有悄晃,再往前看,還有一個html標(biāo)簽凿滤。
目前我們觀察的結(jié)果是妈橄,主html嵌套一個main_screen鼠渺,在main_screen又嵌套了一個main_iframe_0。所以我們先從主html切換到main_screen眷细,再從main_screen切換到main_iframe_0。代碼如下:
driver.switch_to.frame('main_screen')
time.sleep(2) #不加延遲鹃祖,會概率性切換不過去
driver.switch_to.frame('main_iframe_0')
3)元素定位
基本信息的元素溪椎,onclick屬性包含“arrMaintain”。但是如果這樣定位恬口,會有兩個元素校读,一個是“基本信息”,另一個是“流量統(tǒng)計(jì)”祖能∏革可以根據(jù)元素的文本二次判斷。代碼如下:
eles=driver.find_elements_by_css_selector("a[onclick*='arrMaintain']")
for ele in eles:
if '基本信息'in ele.text:
ele.click()
break
定位到基本信息后养铸,點(diǎn)擊雁芙。
4)再次frame處理
本以為點(diǎn)擊后,繼續(xù)查找ip元素即可钞螟。但是不料竟然需要重新切換frame兔甘。就好像點(diǎn)擊基本元素后,整個driver刷新了一樣鳞滨,這塊是重點(diǎn)洞焙。(如果已經(jīng)切換過frame,driver對象刷新后拯啦,需要重新切換frame澡匪,有興趣的同學(xué)可以試下)
#點(diǎn)擊后,又回到主html
driver.switch_to.frame('main_screen')
time.sleep(2)
driver.switch_to.frame('main_iframe_0')
5)ip元素定位
ip元素父元素有一個div元素褒链,id是wan_info唁情。而且ip是tbody下第5個tr,當(dāng)前tr下面的第3個td碱蒙。
css選擇器語法是#wan_info tr:nth-of-type(5) td:nth-of-type(3)
代碼如下:
ip=driver.find_element_by_css_selector('#wan_info tr:nth-of-type(5) td:nth-of-type(3)').text
終于大功告成荠瘪,通過本次實(shí)踐,frame需要注意如下:
1.定位到當(dāng)前元素赛惩,多找找父節(jié)點(diǎn)哀墓,有沒有html標(biāo)簽,再找找有無frame和iframe標(biāo)簽喷兼。
2.連續(xù)frame切換篮绰,如果偶發(fā)性報(bào)錯,可以加入延遲試試季惯。
3.無法定位元素時吠各,如果保證之前已經(jīng)切換過frame臀突,考慮是否需要再次切換frame。
匯總代碼如下:(關(guān)鍵信息使用xxxxxx表示)
from selenium import webdriver
import time
driver=webdriver.Chrome(r'D:\webdriver\chromedriver.exe')
driver.get('xxxxxxxxxxxxxxxxxxxxx')
driver.implicitly_wait(10)
#router login
driver.find_element_by_css_selector("#dl_margin input[name='account']").send_keys('xxxxx')
driver.find_element_by_css_selector("#dl_margin input[name='password']").send_keys('xxxxx')
driver.find_element_by_id('longin_button').click()
#get ip
driver.switch_to.frame('main_screen')
time.sleep(2)
driver.switch_to.frame('main_iframe_0')
eles=driver.find_elements_by_css_selector("a[onclick*='arrMaintain']")
for ele in eles:
if '基本信息'in ele.text:
ele.click()
break
time.sleep(2)
#點(diǎn)擊后贾漏,又回到主html
driver.switch_to.frame('main_screen')
time.sleep(2)
driver.switch_to.frame('main_iframe_0')
ip=driver.find_element_by_css_selector('#wan_info tr:nth-of-type(5) td:nth-of-type(3)').text
print(f"當(dāng)前wan口ip是:{ip}")
driver.quit()