Selenium定位不到指定元素原因之iframe(unable to locate element)
浏览过程中,图片中的内容可能太小,无法看清,可以>右键>在新标签中打开
Outline
项目原因,需要用selenium实现模拟登陆、模拟上传文件,自然就需要模拟点击【上传】按钮;
模拟点击之前需要通过selenium提供的“方法”去定位到要点击的元素;
模拟登陆过程中,全程都可以定位到需要点击的元素,但登陆后需要定位点击【上传】按钮时问题来了;
元素明明在那放着,就是定位不到,这个问题困扰了一下午还没解决,最终走到了iframe这个一步,才得以解决。
什么是iframe
解决问题之前很有必要先了解下什么是iframe:
HTML内联框架元素 <iframe> 表示嵌套的浏览上下文,有效地将另一个HTML页面嵌入到当前页面中。在HTML 4.01中,文档可能包含头部和正文,或头部和框架集,但不能包含正文和框架集。
但是,<iframe>可以在正常的文档主体中使用。每个浏览上下文都有自己的会话历史记录和活动文档。包含嵌入内容的浏览上下文称为父浏览上下文。顶级浏览上下文(没有父级)通常是浏览器窗口。
iframe是HTML三种结构中的框结构,框结构中还有另外两个元素:
frameset和frame,但它们都已废弃,不再推荐使用。
HTML中iframe展示
如下图所示,右侧代码中圈出来的iframe标签,渲染之后在前端显示的就是左侧圈出来的区域;
也就是此iframe嵌套在该HTML框架中。

如何说明iframe是一个独立部分、是被嵌套到HTML框架内部的?见下图:
将iframe标签中的 src=/default/research/redirect 复制出来在地址栏进行链接替换,会发现此时的页面只有iframe独立部分,之前页面中的banner不见了。

参考:
selenium定位元素
selenium模拟登陆操作
部分代码:
def auto_login(self):
# 获取浏览器窗口对象
driver = webdriver.Chrome()
# 打开浏览器进入指定地址
driver.get('https://ycjq.95358.com/research') # selenium进行元素定位、填写内容
driver.find_element_by_name("CyLoginForm[username]").send_keys("你的账号")
driver.find_element_by_name("CyLoginForm[pwd]").send_keys("你的密码") # 这里图像识别获取验证码 def valideCode():
# driver.find_element_by_name("valideCode").send_keys("") # selenium进行元素定位、模拟点击(登陆)
time.sleep(10)
driver.find_element_by_id("btnSubmit").click()
页面分析:
根据标签的“name”、“id”等,进行元素定位,然后模拟操作。

执行上述代码,你会发现会自动打开浏览器,进入指定地址,然后会自动进行账号密码的输入,并且自动点击“登陆”;
然后会进行登陆后的页面跳转。
整个流程很正确也很合理,但页面跳转之后再进行元素定位、模拟点击时就有坑了。
切换iframe
上一步“模拟登陆”时,HTML页面并不涉及 iframe 标签,但登陆过后就含有 iframe标签了。
所以再通过selenium进行模拟点击时就要切换iframe了。
在用selenium定位页面元素的时候会遇到定位不到的问题,明明元素就在那儿,用firebug也可以看到,就是定位不到,问题很有可能就出在iframe上。
问题复现
错误代码复现:
def auto_login(self):
# 获取浏览器窗口对象
driver = webdriver.Chrome()
# 打开浏览器进入指定地址
driver.get('https://ycjq.95358.com/research') # selenium进行元素定位、填写内容
driver.find_element_by_name("CyLoginForm[username]").send_keys("你的账号")
driver.find_element_by_name("CyLoginForm[pwd]").send_keys("你的密码") # selenium进行元素定位、模拟点击(登陆)
time.sleep(10)
driver.find_element_by_id("btnSubmit").click()
time.sleep(10)
# 定位到“上传”按钮
driver.find_element_by_id('notebook_list_info').click()
可以确定下图的元素定位位置无误,理应可以通过selenium模拟点击的,但模拟点击之后一直提示找不到标签:


问题解决
问题出现之后,进行相关问题搜索,五花八门,各种解决方案,用了一下午,各种尝试,最终确定问题出在iframe。
只有切换到iframe里面,selenium才能定位到 iframe里面的元素。
切换iframe
selenium提供了switch_to.frame()方法来切换frame
switch_to.frame(reference)
注意:
可能你会这样写:switch_to_frame(),但会发现,这段代码被加上“删除线”了;
原因是这个方法已经out了,之后可能被废弃,建议switch_to.frame()

switch_to.frame(reference)中的reference是传入的参数,用来定位frame,可以传入id、name、index以及selenium的WebElement对象。
如下图中的 id、name。
如果没有id、name属性的化,可以通过xpath匹配WebElement对象进行定位。

正确定位代码:
def auto_login(self):
# 获取浏览器窗口对象
driver = webdriver.Chrome()
# 打开浏览器进入指定地址
driver.get('https://ycjq.95358.com/research') # selenium进行元素定位、填写内容
driver.find_element_by_name("CyLoginForm[username]").send_keys("你的账号")
driver.find_element_by_name("CyLoginForm[pwd]").send_keys("你的密码") # 这里图像识别获取验证码 def valideCode():
# driver.find_element_by_name("valideCode").send_keys("") # selenium进行元素定位、模拟点击(登陆)
time.sleep(10)
driver.find_element_by_id("btnSubmit").click()
time.sleep(10)
# 切换iframe
driver.switch_to.frame('research')
driver.find_element_by_id('notebook_list_info').click()
执行代码之后即可正确模拟点击”上传“按钮。
参考:https://blog.csdn.net/huilan_same/article/details/52200586
Selenium定位不到指定元素原因之iframe(unable to locate element)的更多相关文章
- 解决Selenium弹出新页面无法定位元素问题(Unable to locate element)
Python 2.7 IDE Pycharm 5.0.3 环境细节详见Python+Selenium+PIL+Tesseract真正自动识别验证码进行一键登录 对于同一页面无法定位元素问题请见姊妹篇解 ...
- org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element(识别不到想要的元素) 想获取 ...
- 元素无法定位问题 NoSuchElementException: Message: no such element: Unable to locate element 解决方法
定位网页上某个按钮时,总是报错元素定位不到,具体如下:NoSuchElementException: Message: no such element: Unable to locate elemen ...
- Selenium定位二 --多个元素定位方法 和层级定位方法
定位多个元素: findElements()方法可以返回一个符合条件的元素List 组 如: public void hitUpdatePersonnel(WebDriver driver, int ...
- 【Python】selenium调用IE11浏览器,报错“找不到元素”NoSuchWindowException: Message:Unable to find element on closed window
当编写自动化脚本,定位浏览器元素时,报如下错误: 代码: >>> # coding=utf-8 >>> from selenium import webdriver ...
- selenium+python,解决selenium弹出新页面,无法定位元素的问题(报错:Unable to locate element:元素)
1.问题发生描述: 从一个页面进行点击等操作,页面跳转到第二个页面,对第二个页面中的元素,采取任何措施定位都报错,问题报错点如下: 2.出现问题的原因: 窗口句柄还停留在上一个页面,对于当前新弹出的页 ...
- selenium定位方式-获取标签元素:find_element_by_xxx
定位方式取舍# 唯一定位方式.多属性定位.层级+角标定位(离目标元素越近,相对定位越好) # 推荐用css selector(很少用递进层次的定位)# 什么时候用xpath呢? 当你定位元素时,必须要 ...
- selenium 定位无标签的元素
转载需注明出处. 如: ::before 伪元素xpath css_selector. id. class_name各种定位失效,可以选择用, .get_attribute('innerHTML')方 ...
- 如果遇到找不到元素如何处理? Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"id","selector":"investmentframe"}
常见几种原因与应对,详细参见http://www.blogjava.net/qileilove/archive/2014/12/11/421309.html 1,动态ID无法找到,用xpath路径解决 ...
随机推荐
- erlang supervisor中启动普通的进程
文字部分转自: http://1234n.com/?post/qou3eb supervisor的子进程 一开始使用supervisor的时候,我用的是init/1返回子进程规格列表的方式,并且所有子 ...
- maven仓库镜像配置
<!-- 阿里云仓库 --> <mirror> <id>alimaven</id> <mirrorOf>central</mirror ...
- jsp中判断对象是否存在
<!-- 如果user对象存在,则显示用户名,如果不存在,则显示空值--> <input type="text" id="userName" ...
- phoneGap 3.5 eclipise 模拟器调试
最近想搞phoneGap开发,可是一看 http://www.phonegapcn.com/ phoneGap中文网 FUCK .phoneGap 还在1.0.0 里混呢.现在phoneGap 3.5 ...
- Bootstrap打印问题
删除bootstrap的样式引用,就可以正常打印预览了. bootstrap 设置了@media print相关属性导致 @media print { * { color: #000 !importa ...
- java网络编程2-URL和URI
//创建url可以指定请求的url协议,但不同的jvm支持的协议可能不相同(大部分支持http.file.https) //构造只判断字符串中的协议支不支持,而不判断url的正确性 URL url=n ...
- raw_input() 与 input()对比
转载来自http://www.cnblogs.com/way_testlife/archive/2011/03/29/1999283.html 这两个均是 python 的内建函数,通过读取控制台的输 ...
- PowerDesigner使用教程3
from:http://www.cnblogs.com/langtianya/archive/2013/03/08/2949118.html PowerDesigner是一款功能非常强大的建模工具软件 ...
- Lingo (Spring Remoting) : Passing client credentials to the server
http://www.jroller.com/sjivan/entry/lingo_spring_remoting_passing_client Lingo (Spring Remoting) : P ...
- 高性能javascript 文件加载阻塞
高性能javascript javascript脚本执行过程中会中断页面加载,直到脚本执行完毕,此操作阻塞了页面加载,造成性能问题. 脚本位置和加载顺序:如果将脚本放在head内,那么再脚本执行完 ...