当前位置: 首页 > 知识库问答 >
问题:

Selenium-Stale元素引用:元素未附加到C中的页面文档#

殷永嘉
2023-03-14

我使用selenium从网站的表格中获取数据,以进行分析。我必须扫描一张大约1000行的表格。

我知道这个页面有Javascript,可以自动更新DOM。但是表中的行太多了,所以当我扫描代码时,总是抛出一个异常。

我尝试了这个代码:

Boolean breakIt = true;
List<IWebElement> result = new List<IWebElement>();
while (true)
{
    breakIt = true;
    try
    { 
          IWebElement baseTable = browser.FindElementById("column2");
          ReadOnlyCollection<IWebElement> rowsTable = baseTable.FindElements(By.XPath("id('oTable')/table/tbody/tr"));
          foreach (IWebElement rows in rowsTable) {
                if (rows.FindElements(By.XPath("td")).Count == 10)
                     result.Add(rows);
          }
          if (breakIt)
          {
                 break;
          }
     }
     catch (StaleElementReferenceException ser)
     {
          if (ser.Message.Contains("element is not attached"))
          {
                 browser.Refresh();
                 browser.WaitForPageToLoad();
                 browser.GoToFrame(browser.FindElementByXPath("//*[@id='form1']/div[3]/iframe"));
                 breakIt = false;
          }
     }
}

它抛出一个异常,如:

陈旧元素引用:元素未附加到页面文档。

你有办法解决我的问题吗?我认为使用多线程是最好的方法。

但是我尝试了多个Thread,它也返回异常。

我认为在得到rowsTable之后。计数。把这个除以2。创建两个线程运行这个?

共有1个答案

朱丰
2023-03-14

我也有类似的情况。我的清单没有那么大,所以我将提出的一些想法不适用于我的案例,因此我没有测试它们。

假设表定期更新,那么如果第一次表扫描在StaleElementReferenceExcepthtml" target="_blank">ion上失败,第二次表扫描将在下一个安静期开始时开始,并且在下一次更新之前很有可能成功。前提是您可以比更新周期更快地完成扫描。

waitForAngular()是从https://stackoverflow.com/a/30540634/6081394或https://stackoverflow.com/a/38657507/6081394的方法,或使用两个相继是额外的肯定;)

var finished = false;
for (var i = 0; i < 10; i++)
{
    try
    {
        waitForAngular()
        // scan table here
        finished = true;
        break;
    }
    catch (StaleElementReferenceException e)
    {
        continue;
    }
}
if (!finished)
{
    // test flaked out
}

这是我自己做的。

本地selenium比Remote更快,因此使用以前的方法,在页面更新之前完成表扫描的可能性要高得多。我知道这不现实,但仍然是一个选择。

如果表只是刷新,但数据(和行数)是相同的,您可以首先计算表中的行,然后一次检查10行,重试,以防出现像以前一样的StaleElementReequceExc0019

您可以使用CSS查询行范围,请参阅https://stackoverflow.com/a/28061560/6081394

tr:nth-child(n+2):nth-child(-n+4)

JavaScript执行是事件驱动和单线程的。这保证了当注入的JavaScript正在运行时,更新页面的脚本不会运行。然而,可能发生的是,当表处于更新的中间时,脚本会被执行。你必须检测到这一点,退出,再次运行脚本,并希望下次会更好。看见https://stackoverflow.com/a/6285793/6081394举个例子。

如果我面对一张大桌子和快速更新,我会这样做。

例如,selenium驱动程序最终在页面中执行JavaScript来完成他们的工作,并且该执行是单线程的,因为在单个浏览器选项卡中的所有JavaScript执行都是单线程的。因此,您编写的任何多线程C#测试最终都会以序列化的顺序顺序执行Selenium操作。所以多线程不是一个解决方案。

 类似资料:
  • 我得到了这个错误,当我试图点击一个下拉ID: 我想用这个代码: 有没有什么方法可以防止无限循环,或者更好的方法在我得到这个异常后点击id?

  • 所以我正在尝试制作一个在flickr上运行的程序,我已经准备好了所有的东西,直到cookies弹出,它打败了我。 我正在尝试切换到这个iframe,这样我就可以使用“全部接受”按钮。然而,iframe的ID是动态的,所以为了避免这个问题,我尝试以标题为目标。 但是我现在收到了这个错误消息。 我已经尝试添加了10秒的等待时间来给它加载时间,我知道错误的原因是元素不再连接到DOM,但我不知道要使用什么

  • 我正在构建一个刮网站的c#应用程序。我认为这个问题是因为页面在一次又一次提交表单后被重新加载而导致的。我必须从选择列表中选择一个选项,然后按回车键,等待页面重新加载新结果。但是重新加载后会导致此错误; 我的代码是这样的; 我也尝试过类似的东西; 时间不多了,我有个例外,时间不多了。

  • 我试图理解为什么在我试图显示从网站获取的项目时会出现错误。我也在使用谷歌chrome浏览器。 这是我代码的其他部分 每当我使用"chromeDriver.FindElement(By.ID(something.link.text))。单击();",它会给出一个错误。我不能显示我提取的数据。 在错误消息中,它显示“OpenQA.Selenium.StaleElementReferenceExcept

  • 我有一个下拉列表,我第一次能够按索引选择元素。当我第二次尝试选择元素时,它会抛出陈旧的元素引用错误。我尝试了try catch block,显式等待,但没有任何效果。

  • 我的程序抛出一条错误消息“stale element reference:element未附加到页面文档”。当我查看前面的帖子(如Python Selenium陈旧元素修复)时,我发现我没有在调用click函数后更新url。我更新了网址。然而,它并没有解决这个问题。谁能指出我哪里出错了?下面是我的代码: