【问题标题】:Selenium2 Webdriver C# .Click() List - Stale Reference ExceptionSelenium Webdriver C# .Click() 列表 - 过时的引用异常
【发布时间】:2026-01-29 10:30:02
【问题描述】:

我需要一些帮助,因为当我尝试解析要点击的标签列表时,我不断收到 StaleElementReference。

我所做的是在页面上迭代页面并生成一个带有所有 a 标签的对象 List

    private List<IWebElement> _pageLinks;
    public List<IWebElement> pageLinks
    {
        get
        {
            if (_pageLinks == null)
            {
                _pageLinks = InfoDriver.FindElements(By.TagName("a")).ToList();
            }
            return _pageLinks;
        }
    }

然后我想解析这个列表,然后点击每一个,然后返回到引用它的页面。

    private static SeleniumInformation si = new SeleniumInformation(ffDriver);

        si.pageLinks.ForEach(i =>
        {
            i.Click();
            System.Threading.Thread.Sleep(1000);
            ffDriver.Navigate().Back();
        });

发生的情况是,在第一次单击后,它会转到新页面,然后返回到起始页面,但无法获取下一个链接。我已经尝试将它设置为静态元素,设置一个支持字段,以便它检查是否已经存在数据但是似乎在单击时 IwebElement 会丢失列表并且它也不会重建列表所以我得到了未处理 StaleElementReference 异常且未在缓存中找到元素。

这是 Selenium 中 IWebElement 类的错误还是我做错了什么?任何帮助将不胜感激。

【问题讨论】:

    标签: c# selenium-webdriver


    【解决方案1】:

    这是预期的行为。您离开了元素所在的页面。当您向后导航时,它是一个新页面,并且该元素不再存在。

    为了解决这个问题,如果可以的话,我建议绕过 Bys。假设您的锚链接都具有唯一的 href,您可以改为生成如下列表(java 代码,但应转换为 c#):

    private static List<By> getLinks(WebDriver driver)
    {
        List<By> anchorLinkBys = new ArrayList<By>();
        List<WebElement> elements = driver.findElements(By.tagName("a"));
        for(WebElement e : elements)
        {
            anchorLinkBys.add(By.cssSelector("a[href=\"" + e.getAttribute("href") + "\"]"));
            //could also use another attribute such as id.
        }
        return anchorLinkBys;
    }
    

    我不知道您的页面的构成,所以我不知道是否可以动态生成唯一标识您想要的元素的 By。例如,如果所有元素都具有相同的父元素,则可以使用 css 级别 3 选择器 nth-child(n)。希望您从上面的代码中得到一些想法。

    【讨论】:

    • 不幸的是,这是问题的一部分。可能有重复的href,重复的标签文本,在某些情况下,元素上没有ID。我正在做的概念是将整个站点的每个页面存储在一个列表中,然后为每个页面存储一个链接列表。然后测试每个链接以验证功能是否正确。
    【解决方案2】:
        private void YourTest()
        {
            IWebDriver browserDriver = new FirefoxDriver();
            browserDriver.Navigate().GoToUrl(pageUrl);
            int linkCount= browserDriver.FindElements(By.TagName("a")).Count;
    
            for (int i = 0; i <= linkCount-1; i++ )
            {
                List<IWebElement> linksToClick = browserDriver.FindElements(By.TagName("a")).ToList();
                linksToClick[i].Click();
                System.Threading.Thread.Sleep(4000);
                if(some boolean check)
                {
                  //Do something here for validation
                }
                browserDriver.Navigate().Back();
            }
            broswerDriver.Quit();
        }
    

    【讨论】:

    • 我不得不使用 IList 而不是 List