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路径解决 ...
随机推荐
- HDU 4969 Just a Joke(积分)
HDU 4969 Just a Joke pid=4969" target="_blank" style="">题目链接 推公式,r′=dr/d ...
- Flask系列:数据库
这个系列是学习<Flask Web开发:基于Python的Web应用开发实战>的部分笔记 对于用户提交的信息,包括 账号.文章 等,需要能够将这些数据保存下来 持久存储的三种方法: 文件: ...
- linux学习笔记34--命令rcp和scp
rcp代表“remote file copy”(远程文件拷贝).该命令用于在计算机之间拷贝文件.rcp命令有两种格式.第一种格式用于文件到文件的拷贝:第二种格式用于把文件或目录拷贝到另一个目录中. 1 ...
- 跟着百度学PHP[14]-PDO的预处理语句2
在$sql = $pdo -> prepare("insert into users(gold,user,password) values(?,?,?)"):条语句我们不仅仅 ...
- Solr学习01:Solr基础知识
一.什么是solr 首先,要了解下Solr是什么,以下是官方的描述. Solr是一个来自Apache Lucence项目,是一个热门开源的企业级搜索平台.为目前世界上相当多的大型互联网站点提供搜索和导 ...
- PHP——smarty模板(做登录页面和主页面)
denglu.php <?php include "init.inc.php"; $smarty->assign("action","ma ...
- 解读MT7620A上的DTS文件
DTS文件,即Device Tree Source,是某些芯片(在Openwrt的target/linux/中,至少ramips,lantiq和BRCM有此文件)用于描述硬件设备资源的文件.此文件是驱 ...
- 在linux下安装配置rabbitMQ详细教程
在linux下安装配置rabbitMQ详细教程 2017年12月20日 17:34:47 阅读数:7539 安装Erlang 由于RabbitMQ依赖Erlang, 所以需要先安装Erlang. Er ...
- idea传入HttpServletRequest时显示cannot resolve symbol的问题
在使用idea ide的时候,在控制器中我需要获取HttpServletRequest这个request对象,编译时出现cannot resolve symbol的问题,然后网上查找资料,这里记录一下 ...
- Androidz之字符串国际化问题
(1)字符串的国际化 在res下写两个values 注意:命名方式都是固定的 一个中文版:values-zh 一个英文版:values-en 可是<string name 要写成一样的,这样会 ...