Selenium 【已解决】急!遇到一个元素定位问题,没找到成功的解决方案

大海 · 2022年04月29日 · 最后由 Ouroboros 回复于 2022年05月05日 · 6975 次阅读

我的业务需求

实际对应的元素信息

# dropdown_button = driver.find_element(By.CSS_SELECTOR, '.elevatorMonitoringDown')
# dropdown_button = driver.find_element(By.XPATH, '//div[@id="content"]/div/img[@class="elevatorMonitoringDown"]/@src')
# dropdown_button = driver.find_element(By.CLASS_NAME, 'elevatorMonitoringDown')

目前已经尝试的方案
使用 XPATH, CLASS NAME, CSS SELECTOR,都是提示找不到元素

第一种方案已失败
Message: no such element: Unable to locate element: {"method":"css selector","selector":".elevatorMonitoringDown"}

第二种方案已失败
Message: no such element: Unable to locate element: {"method":"xpath","selector":"//div[@id="content"]/div/img[@class="elevatorMonitoringDown"]/@src"}

第三种方案已失败
Message: no such element: Unable to locate element: {"method":"css selector","selector":".elevatorMonitoringDown"}

希望能在社区的帮助下,找到解决问题的思路,谢谢!

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
最佳回复

最新更新:问题已解决。

解决方案:由于该页面是浏览器弹出的一个新的 TAB 页,所以我在点击下拉按钮之前,试着加了一行 switch_to_new_tab 代码,然后再进行元素的点击操作,这样可以成功了。之所以之前代码没有加这行代码,是因为在自动化跑的过程中,我以为程序默认是在当前新的 TAB 页下进行的,但实际上并不是。

driver.switch_to_new_tab()

最后总结:

# dropdown_button = driver.find_element(By.CSS_SELECTOR, '.elevatorMonitoringDown')
第一种方案验证通过

# dropdown_button = driver.find_element(By.XPATH, '//div[@id="content"]/div/img[@class="elevatorMonitoringDown"]/@src')
第二种方案也是正确的但是元素地址写错误了
重新修正去掉/@src”,正确的地址为 '//div[@id="content"]/div/img[@class="elevatorMonitoringDown"],这样可以验证通过

# dropdown_button = driver.find_element(By.CLASS_NAME, 'elevatorMonitoringDown')
第三种方案,还是验证通过

怎么现在才想到要加一个 switch_to_new_tab?

今天决定尝试最后一种方案,也就是图片识别点击。
在使用 airtest 的 api 进行截图识别定位的时候,发现每次跳转后,开始进行截图点击的时候,代码总是跳回到前一页,最后发现是因为没有进行 switch_to_new_tab,截图的时候默认还是在前一个页面上,导致代码始终找不到图片地址。
鉴于这个情况,我就在自己原有的项目代码中,加入了

driver.switch_to_new_tab()

其他保持不变,等切换到新页面后,才开始进行元素点击。接着重新跑项目代码,发现一次性通过,成功点击到按钮,成功关闭蒙层。

最后补充

driver.switch_to_new_tab()

是 airtest_selenium 自己封装的方法,如果要使用 switch_to_new_tab(),需要导入

from airtest_selenium.proxy import WebChrome
from airtest.core.api import *

原生的代码是

#获取当前浏览器的所有窗口句柄
handles = driver.window_handles
#切换到最新打开的窗口
driver.switch_to.window(handles[-1])
#切换到倒数第二个打开的窗口
driver.switch_to.window(handles[-2])
#切换到最开始打开的窗口
driver.switch_to.window(handles[0])

效果都是一样的,本人已经代码验证通过。

共收到 15 条回复 时间 点赞

在线等

找不到元素的时候,打印 page source 看看先?

有时候 page source 看到的,和你浏览器 elments 看到的会有一些出入。也可能是这个是延迟加载的,你找元素的时候还没加载出来。

先打印 page source 确认有控件,再 find ,会比较稳。

大海 · #12 · 2022年04月29日 Author
仅楼主可见

这就是我之前说的,每个元素要 id😅

没有 xpath 定位不到的元素,1、建议下个 xpath 验证插件,验证你这个 xpath 是否正确 2、添加延迟等待

国文 回复

多么痛的领悟!
page_source 里面,发现这个页面的源码都是 JS,再没有其他多余的内容了。
看来是没法进行点击操作了。

大海 回复

那你上 js 操作吧,比如 driver.execute_script("$(arguments[0]).click()",button)

大海 回复

啥意思,pagesource 可以都是 js?

是的,其实就是点击一个蒙层,让蒙层关闭,这个蒙层下面才是各种数据

通过 xpath 定位在开发者调试工具里能定位到吗?如果能的话,我就不懂了

大海 #11 · 2022年04月29日 Author
江涛依旧 回复

不能

这个是在 1 个 iframe 里面吗
(随便提一下,xpath 到属性@src的目的是?)

大海 #13 · 2022年04月30日 Author
JoyMao 回复

应该不是,是一个蒙层,就是点击下拉按钮,把蒙层给关闭,展示里面的数据,点击底部的按钮,再弹出蒙层覆盖上去。

最新更新:问题已解决。

解决方案:由于该页面是浏览器弹出的一个新的 TAB 页,所以我在点击下拉按钮之前,试着加了一行 switch_to_new_tab 代码,然后再进行元素的点击操作,这样可以成功了。之所以之前代码没有加这行代码,是因为在自动化跑的过程中,我以为程序默认是在当前新的 TAB 页下进行的,但实际上并不是。

driver.switch_to_new_tab()

最后总结:

# dropdown_button = driver.find_element(By.CSS_SELECTOR, '.elevatorMonitoringDown')
第一种方案验证通过

# dropdown_button = driver.find_element(By.XPATH, '//div[@id="content"]/div/img[@class="elevatorMonitoringDown"]/@src')
第二种方案也是正确的但是元素地址写错误了
重新修正去掉/@src”,正确的地址为 '//div[@id="content"]/div/img[@class="elevatorMonitoringDown"],这样可以验证通过

# dropdown_button = driver.find_element(By.CLASS_NAME, 'elevatorMonitoringDown')
第三种方案,还是验证通过

怎么现在才想到要加一个 switch_to_new_tab?

今天决定尝试最后一种方案,也就是图片识别点击。
在使用 airtest 的 api 进行截图识别定位的时候,发现每次跳转后,开始进行截图点击的时候,代码总是跳回到前一页,最后发现是因为没有进行 switch_to_new_tab,截图的时候默认还是在前一个页面上,导致代码始终找不到图片地址。
鉴于这个情况,我就在自己原有的项目代码中,加入了

driver.switch_to_new_tab()

其他保持不变,等切换到新页面后,才开始进行元素点击。接着重新跑项目代码,发现一次性通过,成功点击到按钮,成功关闭蒙层。

最后补充

driver.switch_to_new_tab()

是 airtest_selenium 自己封装的方法,如果要使用 switch_to_new_tab(),需要导入

from airtest_selenium.proxy import WebChrome
from airtest.core.api import *

原生的代码是

#获取当前浏览器的所有窗口句柄
handles = driver.window_handles
#切换到最新打开的窗口
driver.switch_to.window(handles[-1])
#切换到倒数第二个打开的窗口
driver.switch_to.window(handles[-2])
#切换到最开始打开的窗口
driver.switch_to.window(handles[0])

效果都是一样的,本人已经代码验证通过。

大海 回复

学习了

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册