请帮我解决这个问题!
目前,我正在使用 C# 中的 Selenium Firefox 驱动程序抓取一个网站。然而,本网站上的数据是动态填充的,用于涵盖有关 future 日期的数据的表格。
虽然表的结构对于 future 和过去的日期都完全相同,但在我的 selenium 调用期间正在更新的表抛出一个“NoSuchElementException”,涉及显然存在的 IWebElements。
这些是从表中复制的相关 XPath。一个来自过去的日期,它工作得很好,另一个来自 future 的日期,在该日期抛出异常。如您所见,它们是相同的。
XPath 18052015
/html/body/div[1]/div/div[2]/div[5]/div[1]/div/div[1]/div[2]/div[1]/div[7 ]/div[1]/table/tbody/tr[1]/td[1]/div/a[2]
XPath 05022016
/html/body/div[1]/div/div[2]/div[5]/div[1]/div/div[1]/div[2]/div[1]/div[7 ]/div[1]/table/tbody/tr[1]/td[1]/div/a[2]
使用 FindElements(By.XPath(...)) 函数,我使用两个 foreach 循环遍历 Xpath 中突出显示的 tr 和 td,以获取 a[2] header 中的一些文本。在这两种情况下,FireFox Firebug 中的 DOM 在这两种情况下似乎都是相同的。我在这两个表之间观察到的唯一区别是,每隔几秒,与 future 日期相关的表就会更新其值(通过 Firebug 查看时也会重置表)。这里有一段相关的代码,带有一条重要的注释。
foreach (var tr in table.FindElements(By.XPath("div/table/tbody/tr")))
{
foreach (var td in tr.FindElements(By.XPath("td")))
{
if(td.GetAttribute("innerHTML").Contains("some stuff"))
{
// This part is always reached, so condition is satisfied. > x is the relevant value, it is assigned the proper value when the error is thrown, but it still throws an exception.
x = td.FindElement(By.XPath("div/a[2]")).GetAttribute("href").Split('/')[4];
bmID = getBookmakerID(bmName);
}
if(td.GetAttribute("class").Contains("some other stuff"))
{
}
}
你们有没有遇到过类似的问题,你能解决吗?
最佳答案
您能否将 Wait 添加到调用 FindElement 的每个步骤中?请参见下面的示例:
IWait<IWebElement> wait = new DefaultWait<IWebElement>(table);
wait.Timeout = TimeSpan.FromSeconds(5);
wait.PollingInterval = TimeSpan.FromMilliseconds(300);
By locator = By.XPath("div/table/tbody/tr");
ReadOnlyCollection<IWebElement> rows;
wait.Until(e => e.FindElements(locator).Count > 0);
rows = table.FindElements(locator);
foreach (var tr in rows)
{
wait = new DefaultWait<IWebElement>(tr);
wait.Timeout = TimeSpan.FromSeconds(5);
wait.PollingInterval = TimeSpan.FromMilliseconds(300);
locator = By.XPath("td");
ReadOnlyCollection<IWebElement> cells;
wait.Until(e => e.FindElements(locator).Count > 0);
cells = tr.FindElements(locator);
foreach (var td in cells)
{
if (td.GetAttribute("innerHTML").Contains("some stuff"))
{
// This part is always reached, so condition is satisfied. > x is the relevant value, it is assigned the proper value when the error is thrown, but it still throws an exception.
wait = new DefaultWait<IWebElement>(td);
wait.Timeout = TimeSpan.FromSeconds(5);
wait.PollingInterval = TimeSpan.FromMilliseconds(300);
locator = By.XPath("div/a[2]");
IWebElement link2;
wait.Until(e => e.FindElements(locator).Count > 0);
try
{
link2 = td.FindElement(locator);
}
catch (NoSuchElementException ex)
{
throw new NoSuchElementException("Unable to find element, locator: \"" + locator.ToString() + "\".");
}
x = link2.GetAttribute("href").Split('/')[4];
bmID = getBookmakerID(bmName);
}
if (td.GetAttribute("class").Contains("some other stuff"))
{
}
}
}
如果还是报错,可以在Visual Studio中轻松调试测试。
关于c# - Selenium.NoSuchElementException 与动态表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35164614/