【问题标题】:Can't select option: element is found but invisible无法选择选项:找到元素但不可见
【发布时间】:2018-10-12 09:46:26
【问题描述】:

我正在尝试自动化一个不受我控制的网站,因此我无法更改其 HTML 和 CSS。我需要从组合框中选择一个选项。

我可以成功找到一个“select ../>”元素,但是当我尝试通过 SelectByText、ByValue、ByIndex 选择一个选项时,它会导致 ElementNotVisibleException。该页面上的 html 非常复杂,我相信开发人员通过 css 样式分配了“display:none”。我可以导航到包含该组合框的“div”并通过操作单击它,但之后选择一个选项无济于事。在这样单击之后,我会在屏幕上看到一秒钟的选项,然后组合框折叠起来。

有没有可能克服这样的问题?

【问题讨论】:

  • 不是链接问题的副本。这是一个关于抓取的问题,这是一个关于与页面上的 UI 元素交互的问题。请注意,链接问题中的解决方案并未回答此处提出的问题。

标签: selenium selenium-webdriver selenium-chromedriver


【解决方案1】:

由于 Selenium API 试图“以用户为中心”,它不允许与不可见元素进行交互。您可以尝试两种方法:

1) 单击select 元素,然后显式等待option 变为可见。如果页面使用 JavaScript 显示可能会导致轻微延迟的选择选项,这将非常有用。

By bySelect = By.id("id_of_select_element");
By byOption = new ByChained(bySelect, By.xpath(".//option[contains(text(), 'text_of_option')]");

WebElement select = driver.findElement(bySelect);
select.click();
try {
    // wait at-most 5 seconds for element to become visible
    WebElement option = new WebDriverWait(driver, 5)
        .until(ExpectedConditions.visibilityOfElementLocated(byOption)));   
} catch(TimeoutException t) {
    System.err.println("Timed out while waiting for dropdown to become visible: " + byOption.toString());
}

2) 如果上述方法不起作用,您可以稍微侵入一些并执行一些 JavaScript 来强制选择 option。仅建议作为最后的手段。

public void selectDropdownByText(WebDriver driver, WebElement select, String text) {
    ((JavascriptExecutor) driver).executeScript(
        "var select = arguments[0]; for(var i = 0; i < select.options.length; i++) {if(select.options[i].text == arguments[1]) {select.options[i].selected = true; }}", select, text);
}

【讨论】:

  • 我是用 Java 写的,但是如果你使用 C# 或其他一些客户端绑定,当然是一样的东西,但语法不同。
  • 我已经用 C# 重写了它。不理解 JavaScript 代码中索引参数的含义。什么是参数[0]?
  • 哦,我应该将元素和选项文本作为参数传递给 ExecuteScript,对吗?
  • 是的,没错。 executeScript() 的第一个参数中提供的 JavaScript 被 Selenium 包装在一个函数中并执行。其余参数例如selecttext 被传递给该函数并通过 arguments 数组访问(每个 JavaScript 函数的隐式特性)。在这种情况下,arguments[0]select 元素的 DOM 对象,arguments[1] 是要选择的选项的文本。
  • select.options[i].text 不是值,它是可见文本,是吗?
【解决方案2】:

好的,由于 selenium 的“以用户为中心”的行为,引发了 Element is not visible 异常,
根据我的工作经验,我发现,
Selenium 无法选择对客户端不可见的元素。
我的意思是不能选择那些没有出现在 UI Window 上的人,
仍然是那些您可以在 HTML DOM 上检查但无法通过 selenium 访问的内容。
当它们在屏幕上可见时,您可以很好地选择这些元素。

解决方案是在找到选择标签之前,您必须单击它才能获得可见的完整选项标签。
单击使所有需要选择的选项现在对客户可见。 然后你找到那个选择元素,然后在选择标签下选择选项。当这些选项列表在屏幕上完全可见时。

【讨论】:

  • 我有同样的想法,但是当我通过 Actions 执行点击时,actions = new Actions(Driver); actions.MoveToElement(comboBoxDiv).Click().Perform();列表选项出现一毫秒(粗略地说)然后消失,之后,我再次无法选择选项。
  • "...奇怪的行为...", "...限制..." 真的吗?!你了解 Selenium 的用途吗?作为用户,您可以处理页面上的不可见元素吗?
  • @Andersson 好吧,实际上该元素对人类来说是可见的。机器看不到它:)
  • @AshishKamble 感谢您对 StackOverflow 的每一项贡献。您的一些答案对社区非常有帮助。我之前的评论反对您之前发表的评论(现已删除)。再次感谢您的贡献。
  • @DebanjanB 在我的评论中没有看到任何特别之处。 Selenium 自动化复杂的现代网站是极具挑战性的,有很多变通方法等。我没有看到任何奇怪的事实,一个元素对我来说是可见的,但对 Selenium 是不可见的。为什么会以某种方式发生,可能有十几个相互交织的原因。
猜你喜欢
  • 2017-12-25
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多