【问题标题】:How do you fix the "element not interactable" exception?您如何解决“元素不可交互”异常?
【发布时间】:2017-10-22 11:28:41
【问题描述】:

我知道这已经被问过很多次了,但是你如何解决“元素不可交互”异常?

我是 Selenium 的新手,如果我有什么问题,请见谅。

这是我的代码:

button = driver.find_element_by_class_name(u"infoDismiss")
type(button)
button.click()
driver.implicitly_wait(10)

这是 HTML:

<button class="dismiss infoDismiss">
    <string for="inplay_button_dismiss">Dismiss</string>
</button>

这是错误信息:

selenium.common.exceptions.ElementNotInteractableException: Message: 

在说消息之后实际上什么都没有。

我花了很多时间在网上搜索,但没有找到任何可以解决我问题的东西。非常感谢您的回答。

提前致谢。

编辑:将“w”更改为驱动程序,以便于阅读

更新:我刚刚意识到我找到了错误按钮的 HTML!真正的按钮 HTML 如下:

<button class="dismiss">
    <string for="exit">Dismiss</string>
</button>

另外,我使用了答案和 cmets 并编辑了我的代码,如下所示:

button = driver.find_element_by_css_selector("button.dismiss")
w.implicitly_wait(10)
ActionChains(w).move_to_element(button).click(button)

现在我得到一个新错误:

selenium.common.exceptions.WebDriverException: Message: Tried to run command without establishing a connection

错误发生在第 1 行:button = driver.find_element_by_css_selector("button.dismiss")

注意:非常感谢所提供的帮助,谢谢

【问题讨论】:

  • 你确定这个按钮是唯一具有"infoDismiss"类名的元素吗?试试button = w.find_element_by_css_selector("button.dismiss.infoDismiss")
  • 没有,我刚查了,肯定只有一个

标签: python python-3.x selenium selenium-webdriver webdriver


【解决方案1】:

有一种可能是该元素当前不可点击,因为它不可见。造成这种情况的原因可能是另一个元素覆盖了它或者它不在视图中,即它在当前可见区域之外。

试试这个

from selenium.webdriver.common.action_chains import ActionChains

button = driver.find_element_by_class_name(u"infoDismiss")
driver.implicitly_wait(10)
ActionChains(driver).move_to_element(button).click(button).perform()

【讨论】:

  • 我试过了,但它似乎仍然没有点击它。它不会点击它,但也不会引发错误。
  • 我建议你检查它是否真的被点击了。在元素上添加一些点击事件侦听器,以查看是否正在执行点击,而不是直观地检查点击。
  • Rolodophone,在你描述的那种情况下,请尝试ActionChains(driver).move_to_element(button).click(button).perform(),即添加“.perform()”。跨度>
  • @apascualb 进行了更正,感谢您的提醒。
  • 我遇到了类似的问题,我的问题在这里提出:stackoverflow.com/questions/63316796/…。 button=driver.find_element_by_xpath("//*[@id='submitMe']") driver.implicitly_wait(10) ActionChains(driver).move_to_element(button).click(button).perform() 我收到错误消息:javascript错误:无法在“文档”上执行“elementsFromPoint”:提供的双精度值是非有限的。
【解决方案2】:

我刚刚遇到了一个类似的问题,并且能够通过等待按钮“可点击”来解决它。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option('useAutomationExtension', False)
browser = webdriver.Chrome('./chromedriver', options=chrome_options)

browser.get(('YOURWEBSITEHERE.COM'))

button = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button.dismiss')))
button.click()

【讨论】:

  • 我将其命名为“解决方法”,然后是解决方案。但是,好吧... :-D
  • 变量browser从何而来?
  • @Douy789 我编辑了评论来回答你的问题
  • @zypro 我不认为这是一个“解决方法”,这会等到按钮可交互(可点击),这是发布情况下的问题:)
【解决方案3】:

错误“消息:元素不可交互”主要发生在您的元素不可点击或尚不可见时,您应该点击或选择它之前的另一个元素。然后你的元素就会显示出来,你可以修改它。

您可以通过调用is_displayed() 方法来检查您的元素是否可见:

print("Element is visible? " + str(element_name.is_displayed()))

【讨论】:

    【解决方案4】:

    对于那些现在发现这一点并且上述答案不起作用的人,我遇到的问题是屏幕不够大。我在初始化 ChromeDriver 时添加了这个,它解决了问题:

    options.add_argument("window-size=1200x600")
    

    【讨论】:

    • 您的简单解决方案确实节省了我的时间:D。以上所有解决方案都不适合我。
    【解决方案5】:

    老实说,我是通过从库中导入它来做到的:

    from selenium.webdriver.common.keys import Keys
    
    search.send_keys(Keys.RETURN) 
    

    我花了很多时间,最大化按钮,导入计时器“等待”,但不知何故除了这个没有任何效果

    我仍然是业余爱好者,但我想在这里贡献我的解决方案:)

    【讨论】:

      【解决方案6】:

      右键单击并复制完整的 xpath,如下例所示,它肯定会起作用

      driver.find_element_by_xpath("/html/body/div[1]/div[3]/form/div[1]/div[1]/div[3]/center/input[1]").click()
      

      【讨论】:

      • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
      • 这真的很有效
      【解决方案7】:

      多年后再次遇到同样的问题后找到了一种解决方法 - 无法点击元素,即使它应该是可点击的。解决方案是捕获ElementNotInteractable 异常并尝试执行脚本以单击该元素。

      Typescript 中的示例

      async clickElement(element: WebElement) {
          try {
              return await element.click();
          } catch (error) {
              if (error.name == 'ElementNotInteractableError') {
                  return await this.driver.executeScript((element: WebElement) => {
                      element.click();
                  }, element);
              }
          }
      }
      

      【讨论】:

        【解决方案8】:

        我发现使用 Thread.sleep(milliseconds) 几乎对我都有帮助。元素加载需要时间,因此它不可交互。所以我在选择每个值后放置了 Thread.sleep() 。到目前为止,这已经帮助我避免了这个错误。

        try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}
        
                Select nationalityDropdown=new Select(driver.findElement(By.id("ContentPlaceHolderMain_ddlNationality")));
        
                nationalityDropdown.selectByValue("Indian");
        
                try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}     
        

        【讨论】:

          【解决方案9】:

          使用除 x_path 之外的元素的 id。它将 100% 工作

          【讨论】:

            【解决方案10】:

            先通过xpath搜索元素:

                buttonNoInteractable = browser.find_element_by_xpath('/html/body/div[2]/div/div/div[2]/div/div/div[2]/div/table[2]/thead/tr/th[2]/input')
            

            然后等待元素可点击:

                buttonNoIteractable.click()
                time.sleep(10)
            

            或者按类名搜索。您可能需要将等待时间从 10 秒到 30 秒不等。

                send = browser.find_element_by_name('stacks') send.click()
            

            【讨论】:

              【解决方案11】:

              这个问题的两个主要原因在这里有很好的记录elements not interactable reason

              所以有两种解决方案,在大多数情况下显式等待会更好

              这里提供基于python的解决方案

              隐式等待

              driver.implicitly_wait(20)

              python中的显式等待

              # impor these stataments 
              from selenium.webdriver.support import expected_conditions as EC
              from selenium.webdriver.support.ui import WebDriverWait 
              from selenium.webdriver.common.by import By
              
              # then you can run like below
              userNameTextBox=wait.until(EC.visibility_of_element_located((By.NAME, "login")))
              userNameTextBox.send_keys(username)
              

              请注意,在 By 之后的所有内容都应使用大写字母,无论是 id 、 xpath 等

              Expected conditions for explicit wait

              【讨论】:

                【解决方案12】:

                我遇到了一个问题,即 2 个按钮的 ID 完全相同。完整 XPath 是解决问题的一种方法,但在不断变化的环境中,完整 XPath 经常会发生变化。

                我第一次使用Chrome.FindElement(By.Id("btnOpenLayawaysContinue") 时它起作用了,但第二次它没有,因为第二次引用了第一个在 DOM 中但在页面上不可见的元素。

                所以我做了一个列表,然后做了一个 for-each,里面有一个 try-catch

                TheBtns = Chrome.FindElements(By.Id("btnOpenLayawaysContinue")).ToList();
                foreach(IWebElement Btn in TheBtns) {
                    try {
                        Btn.Click();
                        Thread.Sleep(1000);
                        return;
                    } catch {}
                }
                

                【讨论】:

                  【解决方案13】:

                  弹性盒大小由屏幕大小决定。所以你应该把屏幕大小设置为 selenium 驱动程序。

                  在我的情况下这是可行的

                          self.driver.set_window_position(0, 0)
                          self.driver.set_window_size(1400, 900)
                  

                  【讨论】:

                    【解决方案14】:

                    使用xpath会更好

                    from selenium import webdriver
                    driver.get('www.example.com')
                    button = driver.find_element_by_xpath('xpath')
                    button.click()
                    

                    【讨论】:

                    • 你为什么这么认为?
                    【解决方案15】:

                    对于html代码:

                    test.html

                    <button class="dismiss"  onclick="alert('hello')">
                        <string for="exit">Dismiss</string>
                    </button>
                    

                    下面的 python 代码对我有用。你可以试试看。

                    from selenium import webdriver
                    import time
                    
                    driver = webdriver.Chrome()
                    driver.get("http://localhost/gp/test.html")
                    button = driver.find_element_by_class_name("dismiss")
                    button.click()
                    time.sleep(5)
                    driver.quit()
                    

                    【讨论】:

                    • 在测试自动化中使用 sleep() 被认为是一种不好的做法。
                    • 这并没有解决元素无法交互的任何类型的问题,例如加载覆盖。这个答案没有用。
                    猜你喜欢
                    • 2020-09-28
                    • 1970-01-01
                    • 1970-01-01
                    • 2020-12-08
                    • 2020-11-14
                    • 2019-10-05
                    • 2020-02-11
                    • 2021-03-10
                    • 2017-12-24
                    相关资源
                    最近更新 更多