Selenium 使用 selenium 时遇见的一个奇怪的问题

xuejiangnan · 2022年11月22日 · 最后由 MarvinWu 回复于 2022年11月23日 · 5020 次阅读

定位元素的时候遇到的一个奇怪的问题:给一个输入框输入内容的时候,selenium 服务器返回:element not interactable,我以为是元素没加载出来,就在输入前做了个显示等待。但 selenium 服务器依旧报这个错误。我在输入前面加了个点击事件,服务器返回了新的错误,意思好像是:<td> 把点击事件拦截了,具体报错如下:selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <input id="row1_name" class="input_name" name="name_1" value="" type="text"> is not clickable at point (880, 194). Other element would receive the click: <td>...</td>

HTML 是表格中放了输入框,页面如下,方便查看我把不需要的标签内的东西换成了三个点:

<tbody id="tbody" class="tbody">
    <tr class="tb_row" id="tr_1">
        <td class="td_row row_no">...</td>
        <td class="td_row">
            <input id="row1_name" class="input_name" name="name_1" value="" type="text">
            <!-- 上面这个是我要定位的元素 -->
        </td>
        <td class="td_row">...</td>
        <td class="td_row">...</td>
        <td class="td_oprow">...</td>
    </tr>
</tbody>

我在输入前做了显示等待,而且是等待元素可见后才会返回成功,但是这部分的并没有报错,那就应该是元素已经可见了,代码如下:

def type_text(self, text, loc):
        '''输入值

        Args:
            text (str): 要输入的内容
        '''
        logger.info(f"loc is {loc}, loc type is {type(loc)}")
        WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(loc))
        ele = self.find_element(*loc)
        ele.click()
        ele.send_keys(text)

我用(By.XPATH, "//tr[@id='tr_1']/td/input[@name='name_1']")进行定位,因为这个是表格里的输入框,只有这默认显示的第一行的输入框有 ID,新加的行中的输入框是没有 ID 的,用这种方法定位比较通用,定位第几行的元素改下数字就行了。

我看过了,HTML 里也没有 iframe 标签,不太明白这是怎么回事。
大佬们帮我看看问题出在哪里呀?是表格的元素不能直接操作吗?

共收到 12 条回复 时间 点赞
xuejiangnan 回复

如果层级没写错的话,元素定位你之前的十有问题的,现在这个报的错误是使用一般的方法无法进行点击操作,需要借助 js 来执行
尝试使用以下方法来试下:
element = driver.find_element_by_xpath("//tr[@id='tr_1']/td[2]/input[@name='name_1']")
driver.execute_script("arguments[0].click();", element)

(By.XPATH, "//tr[@id='tr_1']/td[2]/input[@name='name_1']")

是第二个 td 标签吧,我看你文章中写的是第一个

Time 回复

我改下试试,应该不是这个问题,我的 Xpath 在浏览器里试过的,可以定位到需要的元素。

Time 回复

还是这样,跟之前报的错是一样的:

loc is ('xpath', "//tr[@id='tr_1']/td[2]/input[@name='name_1']"), loc type is <class 'tuple'>
Traceback (most recent call last):
......
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <input id="row1_name" class="input_name" name="name_1" value="" type="text"> is not clickable at point (880, 194). Other element would receive the click: <td>...</td>

1、定位方式错了,第一个 td 一般都是表头,具体看 1 楼
2、确定一下有没有滚动条,元素是否被遮挡

F12 可以定位到唯一元素的话,定位应该是没问题的。
input 时报 not interactable 意思是当前元素是非可编辑的,查查是什么导致,最好本地能 debug 一下,或者加截图看看点击时的页面是什么样子;
看你这个 input 有 value 属性,也可以用 js 执行器设置 value 也能达到目的。

PasswordError 回复

定位的语句换了也不行。这个地方没有滚动条,等等我试试加一个鼠标滑动看看行不行。
后面还有几个大佬建议试试 JS,都试试吧。感觉用 JS 应该是可以的。

空空 回复

好了,换成 JS 就行了,好神奇呀。多谢多谢

Time 回复

换成 JS 就好了,多谢大佬鸭

总结:确定可以定位到元素,但是对元素操作失败的时候,可以尝试直接用 JS 修改元素属性。

调用 JS 意味着放弃使用元素交互的方式来执行操作,也就是说万一哪天这个输入框真出 bug 了,自动化脚本也测不出来。

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