硒 - 陈旧的元素参考:元素未附加到页面



我试图理解为什么当我尝试显示从网站获取的项目时它会出错。 我也在使用谷歌浏览器浏览器。

chromeDriver.Navigate().GoToUrl("somewebsites");
chromeDriver.FindElement(By.Id("something.link.text")).Click();
chromeDriver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5));

以及我代码的其他部分

var item = chromeDriver.FindElementsByXPath("//*[starts-with(@id,"g_1_")]/td[3]/span");
foreach (var value in item)
{
Console.WriteLine(value.Text); 
}

每当我使用">chromeDriver.FindElement(By.Id("something.link.text"((时。Click((;">,它给出一个错误。我无法显示我提取的数据。

在错误消息中,它说">OpenQA.Selenium.StaleElementReferenceException:'陈旧的元素引用:元素未附加到页面文档"。我检查了其他帖子,但没有弄清楚。我该如何解决?

正如我所读,硒的响应速度比网站打开时间快得多,所以它给出了错误。此外,很少,它给出硒不能定位元素。有什么建议吗?

编辑:如果我从显示功能中删除">.text",它会显示">OpenQA.Selenium.Remote.RemoteWebElement"。字符串有问题吗?

编辑2:我可以保存我从网站获取的数据,如下所示:

[i]="System.Collections.ObjectModel.ReadOnlyCollection'1[OpenQA.Selenium.IWebElement]">为此,我写了这样的东西:

string[] test= new string[100];
for (int i = 0; i < 100; i++)
{
kaan[i] = driver.FindElements(By.XPath("//*[starts-with(@id,"g_1_")]/td[3]/span")).ToString();
}

如何转换为文本

我没有用过c#,但做过java/selenium。但是,我可以给你克服陈旧的想法。

通常,如果在启动 webelement 后更改了元素属性或其他内容,我们将获得过时异常。例如,在某些情况下,如果用户尝试单击同一页面上的相同元素,但在页面刷新后,会出现过时元素异常。

为了克服这个问题,我们可以创建新的 webelement 以防页面被更改或刷新。下面的代码可以给你一些想法。(它是在java中,但概念是相同的(

例:

webElement element = driver.findElement(by.xpath("//*[@id='StackOverflow']"));
element.click();
//page is refreshed
element.click();//This will obviously throw stale exception

为了克服这个问题,我们可以将 xpath 存储在某个字符串中,并使用它来创建一个新的 webelement。

String xpath = "//*[@id='StackOverflow']";
driver.findElement(by.xpath(xpath)).click();
//page has been refreshed. Now create a new element and work on it
driver.findElement(by.xpath(xpath)).click();   //This works

在这种情况下,我们正在收集一组 webelement 并迭代以获取文本。但是在收集网络元素和gettext抛出过时之后,Web元素似乎有一些变化。我们可以使用循环并随时随地创建元素并获取文本。

for(int i = 0; i<5; i++)
{
String value = driver.findElement(by.xpath("//.....["+i+"]")).getText);
System.out.println(value);
}

希望这对你有帮助。谢谢。

这种类型的错误通常是由更新的 DOM 引起的。我建议您在所有包含javascript/ajax调用的页面上,在与站点交互之前等待这些调用完成。我通常在页面加载后执行此等待,并且在执行某种触发javascript/ajax调用和/或DOM更新的操作时执行此等待。实际上,这意味着在页面加载(或与之交互(后运行以下函数,然后找到要与之交互的元素。

public void WaitForJqueryAjax() {
int delay = MaxdelaySeconds;
while(delay > 0) {
Thread.Sleep(1000);
var jquery = (bool)(this.driver as IJavaScriptExecutor)
.ExecuteScript("return window.jQuery == undefined");
if(jquery) {
break;
}
var ajaxIsComplete = (bool)(this.driver as IJavaScriptExecutor)
.ExecuteScript("return window.jQuery.active == 0");
if(ajaxIsComplete) {
break;
}
delay--;
}
}

我遇到过类似的情况。这里的主要问题是页面需要时间,所以我添加了time.sleep(sec(,它工作正常。

我最初遇到了这个问题,但我通过几个技巧解决了它

  • 等待某个父元素在页面中可见(可能是父容器div(
  • 等待任何 ajax (xhr( 请求在您尝试使用的元素周围完成
  • (
  • 这是诀窍(不要将任何元素存储为实例属性值,始终根据请求获取(这将帮助您从 staleelement(。尝试 c# 6 中的表达式,示例 私有 IWebElement _parentContainer => _driver。FindElement(...(

此外,您可以为 IWebElement 创建抽象的基本控制和一些扩展方法,并在查找元素时执行一些基本的检查操作

对我有用的解决方案是在页面刷新后使用递归创建一个新的 web 元素。这个想法是由santhosh kumar在这个线程中提到的。这是代码片段。

def preventStaleElement(Bool):
while(Bool):
# During the recursion, a new element will be created since the try 
# block is run once more
try:
element = driver.find_element(By.CLASS_NAME, "mouseover_load")
action = ActionChains(driver).move_to_element(element)
action.perform()
except StalElementReferenceException:
preventStaleElement(True)


一般建议:当浏览器在对元素执行任何类型的操作之前已经导航到下一页时,会发生这种类型的错误,因此无法再引用该元素。

要了解导致问题的元素,您可以打印错误的堆栈跟踪,以确定导致问题的确切元素。

可能的解决方法是检查所引用的元素在用户事件之前是否存在/可见或引入时间延迟。

相关内容

  • 没有找到相关文章

最新更新