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路径解决 ...
随机推荐
- Springboot client 常用配置详解
Property name Description Default value spring.boot.admin.client.enabled Enables the Spring Boot Adm ...
- python学习之with...as语句
python中的with...as...语句类似于try...finally...语句: # -*- coding: utf-8 -*- # """ with...as. ...
- django的html模板中获取字典的值
在django的html模板中获取字典中的值应当直接使用 字典.[key] 的方式 {% for i in lists %} <li id="{{i.id}}" class ...
- 重启tomcat但是session仍然有效的解决方法
参考:http://www.blogjava.net/freeman1984/archive/2010/03/30/316901.html server.xml,在你的webapp的Context节点 ...
- mysql查询条件字段值末尾有空格的问题
mark MYSQL的binary解决mysql数据大小写敏感问题的方法
- shell程序练习
#!/bin/sh通知采用bash解释.如果在echo语句中执行shell命令date,则需要在date命令前面加符号&: 编辑完文件之后不能立即执行该文件,需要给文件设置可执行权限.chmo ...
- eclipse中根据方法找到其实现类
面向接口编程中,程序全是面向接口变成调用,在维护别人写的系统的时候怎么样快速定位当前根据接口调用的方法是哪个实体类实现的: Ctrl + T/f4(光标放在需要查看的方法上,然后按Ctrl+T或者F4 ...
- Mysql root密码忘记的解决办法
Windows 版本: 1.打开安装目录下的my.ini 找到 [mysqld] 在下面加入 skip-grant-tables 2. 重启mysql服务 3.打开命令行 依次输入 USE mysql ...
- C语言 函数指针一(函数指针的定义)
//函数指针 #include<stdio.h> #include<stdlib.h> #include<string.h> //函数指针类型跟数组类型非常相似 / ...
- LTP4J的使用BUG及解决方案
子墨子曾经曰过,LTP是个好模型! car老师oneplus还有bhan开发的LTP4J是个很好的项目,使用起来也非常方便,下面贴几个常见的错误使用引起的bug的log分析 1.现象描述:程序中断,生 ...