selenium web 自动化中的元素不可交互异常

Posted

技术标签:

【中文标题】selenium web 自动化中的元素不可交互异常【英文标题】:element not interactable exception in selenium web automation 【发布时间】:2017-12-24 07:49:33 【问题描述】:

在下面的代码中,我无法在密码字段中发送密码密钥,我尝试单击该字段,清除该字段并发送密钥。但是现在正在使用任何方法。但是如果我调试和测试它就可以工作

  public class TestMail 
   protected static WebDriver driver;

   protected static String result;

   @BeforeClass

   public static void setup()  
              System.setProperty("webdriver.gecko.driver","D:\\geckodriver.exe");

   driver = new FirefoxDriver();

   driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

  

   @Test

 void Testcase1() 

   driver.get("http://mail.google.com");

   WebElement loginfield = driver.findElement(By.name("Email"));
   if(loginfield.isDisplayed())
       loginfield.sendKeys("ragesh@gmail.in");
   
   else
  WebElement newloginfield = driver.findElemnt(By.cssSelector("#identifierId"));                                      
       newloginfield.sendKeys("ragesh@gmail.in");
      // System.out.println("This is new login");
   


    driver.findElement(By.name("signIn")).click();

  // driver.findElement(By.cssSelector(".RveJvd")).click();

   driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
 // WebElement pwd = driver.findElement(By.name("Passwd"));
  WebElement pwd = driver.findElement(By.cssSelector("#Passwd"));

  pwd.click();
  pwd.clear();
 // pwd.sendKeys("123");
 if(pwd.isEnabled())
     pwd.sendKeys("123");
 
 else
     System.out.println("Not Enabled");
 

【问题讨论】:

【参考方案1】:

请尝试像这样选择密码字段。

    WebDriverWait wait = new WebDriverWait(driver, 10);
    WebElement passwordElement = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#Passwd")));
    passwordElement.click();
  passwordElement.clear();
     passwordElement.sendKeys("123");

【讨论】:

【参考方案2】:

尝试将隐式等待时间设置为 10 秒。

gmail.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

或设置显式等待。显式等待是您定义的代码,用于等待特定条件发生,然后再继续执行代码。在您的情况下,它是密码输入字段的可见性。 (感谢 ainlolcat 的评论)

WebDriver gmail= new ChromeDriver();
gmail.get("https://www.gmail.co.in"); 
gmail.findElement(By.id("Email")).sendKeys("abcd");
gmail.findElement(By.id("next")).click();
WebDriverWait wait = new WebDriverWait(gmail, 10);
WebElement element = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("Passwd")));
gmail.findElement(By.id("Passwd")).sendKeys("xyz");

说明:selenium 找不到元素的原因是密码输入字段的id 最初是Passwd-hidden。单击“下一步”按钮后,Google 首先验证输入的电子邮件地址,然后显示密码输入字段(通过将 id 从 Passwd-hidden 更改为 Passwd)。因此,当密码字段仍然隐藏时(即 Google 仍在验证电子邮件 ID),您的网络驱动程序开始搜索 ID 为 Passwd 的密码输入字段,该字段仍然隐藏。因此,会引发异常。

【讨论】:

【参考方案3】:

我遇到了同样的问题,然后找出了原因。我试图输入一个跨度标签而不是一个输入标签。我的 XPath 是用 span 标签编写的,这是错误的做法。我查看了该元素的 html 并发现了问题。然后我所做的就是找到恰好是子元素的输入标签。如果您的 XPath 是使用输入标记名创建的,您只能输入输入字段

【讨论】:

【参考方案4】:

您也可以尝试完整的 xpath,我遇到了类似的问题,我必须单击具有属性 javascript onclick 函数的元素。完整的 xpath 方法有效,没有抛出可交互的异常。

【讨论】:

我也有同样的经历。虽然很高兴理解为什么..【参考方案5】:

在我的例子中,产生异常的元素是一个属于表单的按钮。我换了

WebElement btnLogin = driver.findElement(By.cssSelector("button"));
btnLogin.click();

btnLogin.submit();

我的环境是 chromedriver windows 10

【讨论】:

【参考方案6】:

我将用这个来对冲这个答案:我知道这是废话......而且必须有更好的方法。 (见上面的答案)但我在这里尝试了所有的建议,但仍然没有结果。最终追逐错误,将代码撕成碎片。然后我尝试了这个:

import keyboard    
keyboard.press_and_release('tab')
keyboard.press_and_release('tab')
keyboard.press_and_release('tab') #repeat as needed
keyboard.press_and_release('space') 

这太令人难以忍受了,你必须确保你不会失去焦点,否则你只会在错误的事情上使用标签和间距。

我对为什么其他方法对我不起作用的假设是我试图点击开发人员不希望机器人点击的东西。所以我没有点击它!

【讨论】:

【参考方案7】:

我收到此错误是因为我在 Selenium WebDriver Node.js 函数 By.css() 中使用了错误的 CSS 选择器。

您可以通过在网络浏览器的网络控制台中使用它(Ctrl+Shift+K 快捷键)和 JavaScript 函数 document.querySelectorAll() 来检查您的选择器是否正确。

【讨论】:

【参考方案8】:

如果它在调试中工作,那么wait 必须是正确的解决方案。 我会建议使用明确的wait,如下所示:

WebDriverWait wait = new WebDriverWait(new ChromeDriver(), 5);
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#Passwd")));

【讨论】:

【参考方案9】:

“元素不可交互”错误可能意味着两件事:

一个。 元素未正确渲染:

解决方案就是使用隐式/显式等待

隐式等待:

driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);

显式等待:

WebDriverWait 等待=新 WebDriverWait(驱动程序, 20); element1 = wait.until(ExpectedConditions.elementToBeClickable(By.className("fa-stack-1x")));

b. 元素已渲染,但不在屏幕可见部分:

解决方案只是滚动到元素。根据 Selenium 的版本,它可以以不同的方式处理,但我将提供适用于所有版本的解决方案:

    JavascriptExecutor executor = (JavascriptExecutor) driver;
    executor.executeScript("arguments[0].scrollIntoView(true);", element1);

    假设这一切都失败了,那么另一种方法是再次使用 Javascript 执行器,如下所示:

    executor.executeScript("arguments[0].click();", element1);

    如果您仍然无法点击,那么这可能又意味着两件事:

1.内嵌框架

检查 DOM 以查看您正在检查的元素是否存在于任何框架中。如果是这样,那么您需要在尝试任何操作之前切换到此帧。

    driver.switchTo().frame("a077aa5e"); //switching the frame by ID
    System.out.println("********We are switching to the iframe*******");
    driver.findElement(By.xpath("html/body/a/img")).click();

2。新标签

如果打开了一个新选项卡并且该元素存在于其上,那么您需要再次编写如下代码以在尝试操作之前切换到该选项卡。

String parent = driver.getWindowHandle();
driver.findElement(By.partialLinkText("Continue")).click();
Set<String> s = driver.getWindowHandles();
// Now iterate using Iterator
Iterator<String> I1 = s.iterator();
while (I1.hasNext()) 
String child_window = I1.next();
if (!parent.equals(child_window)) 
    driver.switchTo().window(child_window);
    element1.click() 

【讨论】:

【参考方案10】:

我也遇到了这个错误。我认为这可能是因为该字段不可见。我尝试了上面的滚动解决方案,尽管该字段在受控浏览器会话中可见,但我仍然遇到异常。我提交的解决方案如下所示。看起来事件可以冒泡到包含的输入字段,最终结果是 Selected 属性变为 true。

该字段出现在我的页面中,如下所示。

<label>
  <input name="generic" type="checkbox" ... >
<label>

通用的工作代码或多或少看起来像这样:

var checkbox = driver.FindElement(By.Name("generic"), mustBeVisible: false);
checkbox.Selected.Should().BeFalse();
var label = checkbox.FindElement(By.XPath(".."));
label.Click();
checkbox.Selected.Should().BeTrue();

您需要将其翻译成您的特定语言。我正在使用 C# 和 FluentAssertions。该解决方案适用于 Chrome 94 和 Selenium 3.141.0。

【讨论】:

以上是关于selenium web 自动化中的元素不可交互异常的主要内容,如果未能解决你的问题,请参考以下文章

使用 selenium 函数按名称查找元素时元素不可交互,但在通过 xpath 方法使用查找元素时有效

Selenium C# ElementNotVisibleException:元素不可交互,但该元素实际上是可见的

ElementNotVisibleException:消息:尝试通过 Selenium 和 Python 单击按钮时出现元素不可交互错误

web自动化:selenium原理和元素定位

selenium.common.exceptions.ElementNotVisibleException:消息:元素不可交互,显式等待不能使用Selenium和Python

Selenium : 处理加载屏幕遮挡 web 元素。 (爪哇)