frameset 不用切, frame 需层层切!
很多人在用 selenium 定位页面元素的时候会遇到定位不到的问题, 明明元素就在那儿, 用 firebug 也可以看到, 就是定位不到, 这种情况很有可能是 frame 在搞鬼 (原因之一, 改天专门说说定位不到元素, 可能的一些原因及处理办法).
frame 标签有 frameset,frame,iframe 三种, frameset 跟其他普通标签没有区别, 不会影响到正常的定位, 而 frame 与 iframe 对 selenium 定位而言是一样的, selenium 有一组方法对 frame 进行操作.
1. 怎么切到 frame 中 (switch_to.frame())
selenium 提供了 switch_to.frame() 方法来切换 frame:
switch_to.frame(reference)
1, 不得不提到 switch_to_frame(), 很多人在这样写的时候会发现, 这句话被划上了删除线, 原因是这个方法已经 out 了, 之后很有可能会不支持, 建议的写法是 switch_to.frame()
reference 是传入的参数, 用来定位 frame, 可以传入 id,name,index 以及 selenium 的 webElement 对象, 假设有如下 html 代码 index.HTML:
- <HTML lang="en">
- <head>
- <title>
- FrameTest
- </title>
- </head>
- <body>
- <iframe src="a.html" id="frame1" name="myframe">
- </iframe>
- </body>
- </HTML>
想要定位其中的 iframe 并切进去, 可以通过如下代码:
- from selenium import webdriver
- driver = webdriver.Firefox()
- driver.switch_to.frame(0) # 1. 用 frame 的 index 来定位, 第一个是 0
- # driver.switch_to.frame("frame1") # 2. 用 id 来定位
- # driver.switch_to.frame("myframe") # 3. 用 name 来定位
- # driver.switch_to.frame(driver.find_element_by_tag_name("iframe")) # 4. 用 WebElement 对象来定位
通常采用 id 和 name 就能够解决绝大多数问题. 但有时候 frame 并无这两项属性, 则可以用 index 和 WebElement 来定位:
index 从 0 开始, 传入整型参数即判定为用 index 定位, 传入 str 参数则判定为用 id/name 定位
WebElement 对象, 即用 find_element 系列方法所取得的对象, 我们可以用 tag_name,xpath 等来定位 frame 对象
举个栗子:
<iframe src="myframetest.html" />
用 xpath 定位, 传入 WebElement 对象:
driver.switch_to.frame(driver.find_element_by_xpath("//iframe[contains(@src,'myframe')]"))
2. 从 frame 中切回主文档 (switch_to.default_content())
切到 frame 中之后, 我们便不能继续操作主文档的元素, 这时如果想操作主文档内容, 则需切回主文档.
driver.switch_to.default_content()
3. 嵌套 frame 的操作 (switch_to.parent_frame())
有时候我们会遇到嵌套的 frame, 如下:
- <HTML>
- <iframe id="frame1">
- <iframe id="frame2" />
- </iframe>
- </HTML>
1. 从主文档切到 frame2, 一层层切进去
- driver.switch_to.frame("frame1")
- driver.switch_to.frame("frame2")
2. 从 frame2 再切回 frame1, 这里 selenium 给我们提供了一个方法能够从子 frame 切回到父 frame, 而不用我们切回主文档再切进来.
driver.switch_to.parent_frame() # 如果当前已是主文档, 则无效果
有了 parent_frame() 这个相当于后退的方法, 我们可以随意切换不同的 frame, 随意的跳来跳去了.
所以只要善用以下三个方法, 遇到 frame 分分钟搞定:
- driver.switch_to.frame(reference)
- driver.switch_to.parent_frame()
- driver.switch_to.default_content()
来源: http://www.bubuko.com/infodetail-3363154.html