【问题标题】:Selenium relative locator searches from a WebElement extremely slowSelenium 相对定位器从 WebElement 搜索非常慢
【发布时间】:2012-05-29 10:43:28
【问题描述】:

我正在使用 Selenium 2.0、Firefox 11.0 和 Java 来处理表。我有一个由 td 单元组成的 table 元素,其中一些包含 span 元素中包含的文本,另一些包含在其 value 属性中具有文本的 input 元素。我的目标是获取每个单元格的文本,以便输出表格内容并将它们与预期值进行比较。我以为我会做这样的事情:

Locate the table WebElement by id
List<WebElement> cells = tableElem.findElements(By.xpath(".//td"));

然后我将遍历所有单元格并使用 xpath ".//input" 运行 findElements,如果列表为空,我将在 webElement 上运行 getText,如果列表不为空,我将运行 getAttribute输入元素。

但令我惊讶的是,这需要几分钟才能在 firefox 上运行(我不敢在 IE 上尝试它,这是它应该测试的地方)。当我调试时,很明显瓶颈是来自 td 的 .//input 搜索,这正在杀死我。它超过十秒,因此即使只有几个单元格,我的测试也需要永远进行。我已经尝试了 xpath 的各种细微变化,尝试使用 css 选择器,并继续获得相同的结果。

我想要一些关于如何以不同方式解决此问题或如何优化我当前方法的建议。我希望这只需几秒钟。

我提供了一些示例代码,可以说明我正在经历的减速。这不是我正在抓取的网站,但速度是一样的:

    webDriver.navigate().to("https://accounts.google.com/NewAccount");
    List<WebElement> TDxpath = webDriver.findElements(By.xpath("//td"));
    List<WebElement> TDcss = webDriver.findElements(By.cssSelector("td"));
    for (WebElement td : TDcss) {
        List<WebElement> q = td.findElements(By.cssSelector("input"));
    }
    for (WebElement td : TDxpath) {
        List<WebElement> r = td.findElements(By.xpath(".//input"));
    }

【问题讨论】:

  • 您使用的是哪个版本的 Selenium?在我的机器上执行你的代码只需要 2.8 秒。这与打开页面一起。代码没问题,一定是你的环境有问题。

标签: performance selenium selenium-webdriver web-scraping webdriver


【解决方案1】:

您真的需要浏览器吗?你可以试试HtmlUnitDriver,速度会非常快!

或者你可以作为一个 JS 来做,也只需要一小部分时间和you can get Lists from the script:

(JavascriptExecutor)driver.executeScript(
    "var tds = document.getElementsByTagName('td');"
    "for (var i = 0; i < tds.length; i++) {" +
    "   var inputs = tds[i].getElementsByTagName('input');" +
    "}"
    );

【讨论】:

  • 无论如何,我认为这方面最慢的事情是程序和浏览器之间的通信。你确定你不能想出少于 40 个查询来获取所有数据吗?您在 Google 示例中的用例是什么,您希望输出什么?
  • 我有一个表格,我事先不知道哪些单元格将包含带有文本的输入框,哪些单元格将只包含没有输入框的纯文本。我希望能够编写表格在某些阶段应该是什么样子,并且希望能够调用一些 compareTable 函数来为我完成所有字符串匹配。我需要能够保留单元格的顺序来执行此操作。谷歌示例诚然不是一个真实的用例,但它似乎是一种简单的方法来展示这些查询有多慢。 HtmlUnitDriver 和 JS 是我猜的可能性...
  • 在 google 示例中需要注意的一点是,由于页面上实际上有 9 个表,其中许多是嵌套的,因此做了很多多余的工作。一旦您将搜索减少到其中之一,它也会更快。确保您在真实案例中没有做任何不必要的工作。是的,我想不出任何更简单的查询来获取所有td 元素和所有inputs。通常是其中之一。或者,也许您可​​以利用 XPath 中的 //td[span[text()='some text'] or input[@value='some text']]following 轴来搜索具体的文本单元格。
  • 我曾想过使用 HtmlUnitDriver,但我认为这不会解决问题。按 id 抓取表格不是我的瓶颈,也是我唯一使用驱动程序的事情。其余搜索与特定 WebElement 相关,所以我认为我的问题更多在于 WebElement 类的 findElements。
  • 它在我的电脑上在大约 200 毫秒内完成 HtmlUnitDriver :)。
猜你喜欢
  • 2022-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-12
  • 2016-08-20
  • 2016-12-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多