我需要在某个页面中列出所有传出的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
}
我的问题是:有没有办法列出页面中的所有外发网址,同时保留页面的原始上下文?
答案 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...
}
当您导航回网页时,上面的代码应该,即使链接不按相同的顺序。但是,在这种情况下,你很可能会错过其中一些。