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路径解决 ...
随机推荐
- linux下Samba服务配置
SMB是基于客户机/服务器型的协议,因而一台Samba服务器既可以充当文件共享服务器,也可以充当一个Samba的客户端,例如,一台在Linux 下已经架设好的Samba服务器,windows客户端就可 ...
- redis源码学习_字典
redis中字典有以下要点: (1)它就是一个键值对,对于hash冲突的处理采用了头插法的链式存储来解决. (2)对rehash,扩展就是取第一个大于等于used * 2的2 ^ n的数作为新的has ...
- application/x-www-form-urlencoded和multipart/form-data的区别
在学习<form>元素时,enctype属性有三个值 enctype属性表格: 值 描述 application/x-www-form-urlencoded 在发送前编码所有字符(默认) ...
- HDU 1867 A + B for you again(KMP算法的应用)
A + B for you again Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- tail 命令详解
tail 指令 功能:从指定点开始将文件写到标准输出.使用tail命令的-f选项可以方便的查阅正在改变的日志文件,tail -f filename会把filename里最尾部的内容显示在屏幕上,并且不 ...
- Jquery学习笔记(1)--JQuery原理,与JS对象互换,核心函数
js对象转jQuery对象,$('num'), jQuery对象转js对象,$('num')[0],或$('num').get(0). 1.点击换行,each(),html(),attr(),每个h1 ...
- 获取JQuery UI tabs中被选中的tabs的方法
JQuery标签事件处理实例 如果你正在使用JQuery tabs而且想从基本的功能扩展到自定义的功能,这是你最好知道如何处理JQuery的点击事件. 在这篇文章中: 1.回顾如何添加当tab被点击时 ...
- linux引导模式两种
https://www.ibm.com/developerworks/cn/linux/l-bootload.html
- git上解决代码冲突(merge版)
1.切换到master: git checkout master 2.拉最新代码:git pull origin master 3.切换到提交的分支:git checkout Txxxx 4.合并:g ...
- VC++6.0 打开原来工程突然特别慢或者打不开?
VC++6.0打开原来工程突然特别慢或者打不开? 近几日,对原来工程做了一些修改,感觉打开特别慢,甚至打不开,在Loading Workspace时就卡住了. 解决办法:删除工程文件中的三个文件 ...