Selenium 通过 python 调用 selenium 去点击元素时,报错 ElementClickInterceptedException

Aiden · 2022年01月07日 · 最后由 alex 回复于 2022年01月14日 · 3008 次阅读

我在用 selenium 点击页面元素时,遇到一个问题。
背景:我想点击页面元素 A。我的系统有时候会弹出一个弹窗 B,弹窗 B 过一会会自动消失,不需要点击确定或者取消才能让其消失。
1.现在遇到的问题是,如果弹窗 B 出现的时候,我点击了某个元素,程序就会报错 “ElementClickInterceptedException”。
2.在程序中,我用的是 wait. until(EC.element_to_ be_clickable((By .XPATH, value))) 方法,但是还是没法解决这个问题。用这个方法好像可以解决 “直到页面上显示出元素才会去点击”,但是我弹出弹窗 B 的时候,元素 A 已经被显示出来了。
3.我观察了一下,我的这个弹窗有个这个特点,他有一个 iframe,弹窗有个 class 属性是 “progress-mask-msg”。
4.我还想到一个办法,就是点击元素 A 之前,判断下有没有这个 iframe,如果有,就等他消失再去点击元素 A。但是也不是很靠谱,有时候我去判断的时候,这个小弹窗 B 还没显示,我判断完没有,去点击元素 A 了,然后弹窗 B 才被加载出来,我一点击 元素 A,又崩溃了。

想问在 selenium 中,有没有别的什么方法,真正轮询判断元素可以被点击的,如果不能点击,就等待一会再看能不能点击。
弹窗信息:

弹窗的代码:

我的代码报错信息:

我代码中查找元素的方法:

共收到 8 条回复 时间 点赞

用显示等待 WebDriverWait()

这不是很好解决么,捕获异常等个几秒去重试点击就好了啊

Time 回复

主要想了解下 selenium 自己有没有类似于 element_to_be_clickable 这样的函数,系统自己判断点击是否会报错,如果会,则等待一段时间再点击。
element_to_be_clickable 是不是只能做到判断页面上元素是否加载出来并处于可点击状态,但是当元素上面有 frame 的时候,仍然认为元素是可以点击的。
或者是不是我这边找元素的时候,认为元素是 element_to_be_clickable,然后真正点击的时候,页面忽然弹出了一个 frame,导致点击的时候报错。

如果这个弹窗出现是可预知的
你可以换个思维,保持原来的判断 A 元素可点击不变的前提下
再加一个等待弹窗不可见的判断就好了 (就是等弹窗消失再执行点击)

Tester_谜城 回复

不知道这个弹窗什么时候会消失啊、

Aiden 回复

引发这个报错的原因可能是,在刚要点击这个元素时,有一层新的元素刷新了 dom 树,导致要点击的元素上面覆盖了一层弹框,selenium 应该不会提供这种现成的方法,如果很多地方会遇到这个问题,可以自己封装一个方法,并且把执行方式可以换成:
element = driver.find_element_by_css('div[class*="loadingWhiteBox"]')
driver.execute_script("arguments[0].click();", element)

看了下自己博客之前竟然也遇到过这种问题,你可以试看看
https://blog.csdn.net/Python_BT/article/details/108365605?spm=1001.2014.3001.5501

Aiden 回复

selenium 提供了等待元素可见和等待元素不可见的方法,可以判断的

你这个是很常见的页面加载的 pageblocker 问题,我们的解决办法是封装一个 syncElement 的方法,逻辑是先等待这个元素出现,再等待它消失。基本就能解决这个问题,提升用例的稳定性。你可以参考下这个代码:

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