Selenium webdriver系统无效强制转换异常
本文关键字:转换 异常 无效 webdriver 系统 Selenium | 更新日期: 2023-09-27 17:50:32
为了在c#中为神经网络收集一些测试数据,我想使用Selenium来抓取一些动态生成的数据WSJ。Selenium站点上有一个示例实现,它似乎正好满足了我的需求:查找页面上每个标签的所有输入元素。这个例子在TagName
上搜索,我在ClassName
上搜索,但除此之外,我认为它们是相同的。然而,当我运行这段代码时,用IWebElements
创建IList
可以工作,但是下面的IJavaScriptExecutor
抛出了一个Invalid Cast异常:
无法强制转换类型的对象System.Collections.ObjectModel.ReadOnlyCollection 1(系统。对象)输入System.Collections.Generic.IList 1 (OpenQA.Selenium.IWebElement)
这里是一小段代码,这是"text",我对"num"做同样的事情:
// Find elements by class name
IList<IWebElement> labels = driver.FindElements(By.ClassName("text"));
// get all input elements for every class label
IList<IWebElement> labVals = (IList<IWebElement>)((IJavaScriptExecutor)driver).ExecuteScript(
"var labels = arguments[0], labVals = []; for (var i=0; i < labels.length; i++){" +
"labVals.push(document.getElementById(labels[i].getAttribute('for'))); } return labVals;", labels);
我已经看过这个问题Selenium Web Driver c# InvalidCastException,它可能指向相同的问题,但我不知道所提供的答案如何帮助我。
一个选项可能是将IJavaScriptExecutor
语句分解为"离散"代码,但我不知道如何做到这一点。
一旦我在List
结构中有了文本标签和数据值,我应该能够找到我需要的数字。
这不是使用javascript,但它将工作。我会使用CssSelector方法,通过参数接收您需要的列/行,然后您将使用循环调用此方法以从页面获取所有信息。
检查页面的css这是我从第一列/行
得到的结果table.mdcTable > tbody > tr:nth-of-type(3) > td:nth-of-type(1)
因此,数字"3"与第一行有关,"1"是第一列。所以我们可以创建一个方法来返回你想要的元素:
public IWebElement test(int line, int row)
{
return driver.FindElement(By.CssSelector(string.Format("table.mdcTable > tbody > tr:nth-of-type({}) > td:nth-of-type({})", line + 2, row)));
}
调用此方法将返回包含文本的元素,因此您只需使用'element '即可。将Text'替换为'cell'的值,或者让方法直接返回文本。
public String test(int line, int row)
{
return driver.FindElement(By.CssSelector(string.Format("table.mdcTable > tbody > tr:nth-of-type({}) > td:nth-of-type({})", line + 2, row))).Text;
}
唯一的问题是"Latest"列,因为它们不仅包含数字,还包含一个栏。您必须创建一个方法来只处理这些列。
结果会是这样的:
try
{
int line = 1;
int column = 1;
while(column <= 7)
valueOfTheCell = test(line, column);
getLatestGreen(line); //string.Format("tbody > tr:nth-of-type({0}) > td:nth-of-type(9) > span.text", line)
getLatestRed(line); //string.Format("tbody > tr:nth-of-type({0}) > td:nth-of-type(8) > span.text > b", line)
}
catch (NoSuchElementException)
{
//Exception will be thrown when the code reaches the end of the list
}
我不会说这是最优的,但它是一个选择。如果你想这样做,我可以帮助你解决任何关于如何使用选择器的问题。
转换错误发生,因为IJavascriptExecutor输出一般的System.Object
类MSDN,然后我尝试转换为IWebElement
。这可能在某些情况下起作用,但在这种情况下不起作用。将接收IList
更改为IList<Object>
可以解决强制转换异常。用这个代码运行,然后我用调试器发现所有数据都是用Labels
列表中的代码的第一部分捕获的。IJavaScriptExecutor
只返回空项。所以在我的例子中不需要第二步。