Selenium:列出页面中的传出URL

时间:2014-02-02 13:33:57

标签: javascript dom selenium selenium-webdriver

我需要在某个页面中列出所有传出的URL。

为简化起见,我们假设只有<a>元素可以产生链接。

对于某些元素,网址位于href属性中,而对于其他元素,网址是在用户点击时通过javascript生成的。

我的解决方案是找到页面中的所有<a>元素,然后逐个单击它们。 当我单击外发链接时,浏览器会导航到该链接。为了继续点击其余链接,我导航回原始页面。 但是,当我导航回原始页面时,我得到: org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document

我的代码:

System.setProperty("webdriver.chrome.driver", "drivers/chromedriver.exe")
val driver = new ChromeDriver()

val byHref = By.tagName("a")

// Get all <a> elements
val links = driver.findElements(byHref)

// Resolve all <a> to URLs
val resolvedLinks = links.map(resolveLink(_))

// Resolve <a> to URL
def resolveLink(link: WebElement) : String = {
  // Get href attribute
  val href = link.getAttribute("href")

  // href is javascript?
  if (href == null || href.startsWith("javascript:")) {
    // Click link
    link.click()

    // Get the URL we navigated to
    val navigatedUrl = driver.getCurrentUrl

    // Navigate back to our original page
    driver.navigate().back()

    navigatedUrl 
  }
  else
    href
}

我的问题是:有没有办法列出页面中的所有外发网址,同时保留页面的原始上下文?

1 个答案:

答案 0 :(得分:3)

只要您导航到另一个网页,或者甚至切换到同一网页中的iframe,您在内存中的任何WebElement对象都可能“陈旧”。< / p>

一个可选的解决方案是列出所有元素ID,然后迭代该列表。

我不清楚你正在使用什么语言,但是你可以用Java来做到这一点:

Set<String> linkIds = new HashSet<String>();
List<WebElement> links = driver.findElements(By.tagName("a"));
for (WebElement link : links)
{
    linkIds.add(link.getAttribute("id"));
}
for (String linkId : linkIds)
{
    WebElement link = driver.findElement(By.id(linkId));
    link.click();
    // Add the rest of your code here...
}

但请注意,以上所有内容均假设每个链接都有唯一的ID,并且当您导航回网页时,所有链接都会保留在网页中。如果您访问的特定网页不是这种情况,则需要采用其他方法。

当您导入和导出网页时,假设链接保持相同的顺序,您可以迭代链接ID,而不是迭代链接ID。但这有点效率较低,因为您必须在每次迭代开始时检索所有链接的完整列表。

for (int i=0; true; i++)
{
    List<WebElement> links = driver.findElements(By.tagName("a"));
    if (i >= links.size())
        break;
    links.get(i).click();
    // Add the rest of your code here...
}

当您导航回网页时,上面的代码应该,即使链接不按相同的顺序。但是,在这种情况下,你很可能会错过其中一些。