关键字:python3.6 selenium frame Chrome
selenium自动化测试,frame标签有的时候很令人烦恼。frame类似于在原有主html的基础上又嵌套一个html,而且嵌套的html是独立使用,互不影响。frame的方案经常发生在网页中的导航。
如下:
<!DOCTYPE html>
<html lang="en">
<head>
<title>FrameTest</title>
</head>
<body>
<iframe src="a.html" id="frame1" name="myframe"></iframe>
</body>
</html>
以上的主html里面嵌套了一个iframe标签,也就是里面还有一个a.html。如果我们需要定位的元素在a.html里面,就需要切换到iframe标签后再去定位。
frame相关的标签有frameset,frame,iframe三种。frameset不需要切换,frame和iframe需要切换。切换的方式是swith_to.frame(reference)。
reference可以传入id、name、index以及selenium的WebElement对象。
case:从路由器配置页面抓取到wan口的ip地址。
1)登录
Chrome F12,查看元素后,可以看到当前用户名输入框input标签,有一个name属性account,同时它的父节点有一个id属性是dl_margin。
css选择器语法是:#dl_margin input[name='account']
密码输入框处理同用户输入框,css选择器语法是:#dl_margin input[name='password']
登录按钮直接根据id属性选择:longin_button
2)frame切换
登录后首页,点击基本信息后,显示当前wan口的ip地址
定位到基本信息后,注意到前面的父节点有一个html
切换过去之后,的确有一个iframe标签。
但是就这么结束了吗?没有,再往前看,还有一个html标签。
目前我们观察的结果是,主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”。但是如果这样定位,会有两个元素,一个是“基本信息”,另一个是“流量统计”。可以根据元素的文本二次判断。代码如下:
eles=driver.find_elements_by_css_selector("a[onclick*='arrMaintain']")
for ele in eles:
if '基本信息'in ele.text:
ele.click()
break
定位到基本信息后,点击。
4)再次frame处理
本以为点击后,继续查找ip元素即可。但是不料竟然需要重新切换frame。就好像点击基本元素后,整个driver刷新了一样,这块是重点。(如果已经切换过frame,driver对象刷新后,需要重新切换frame,有兴趣的同学可以试下)
#点击后,又回到主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,当前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
终于大功告成,通过本次实践,frame需要注意如下:
1.定位到当前元素,多找找父节点,有没有html标签,再找找有无frame和iframe标签。
2.连续frame切换,如果偶发性报错,可以加入延迟试试。
3.无法定位元素时,如果保证之前已经切换过frame,考虑是否需要再次切换frame。
汇总代码如下:(关键信息使用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)
#点击后,又回到主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"当前wan口ip是:{ip}")
driver.quit()