为了在C#中收集神经网络的一些测试数据,我想使用Selenium来抓取一些动态生成的数据WSJ。 Selenium网站上有一个示例实现,似乎完全符合我的需要Finding all the input elements to the every label on a page。示例搜索TagName
,我搜索ClassName
,但除此之外,我认为它是相同的。
但是,当我运行此代码时,使用IList
创建IWebElements
有效,但以下IJavaScriptExecutor
会抛出无效的转换异常:
无法投射类型的对象 System.Collections.ObjectModel.ReadOnlyCollection 1 [System.Object] 输入 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
结构中,我就能找到我需要的数字。
答案 0 :(得分:0)
这不是使用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;
}
唯一的问题是“最新”列,因为它们不仅包含数字,还包含一个条形。您必须创建一个方法来只关注这些列。
最终会出现这样的结果:
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
}
我不会说这是最佳的,但它是一种选择。 如果您想这样做,我可以帮助您解决有关如何使用选择器的任何问题。
答案 1 :(得分:0)
发生强制转换错误是因为IJavascriptExecutor输出了一般var value='+12 (345)-678.90[]'.replace(/\D+/g, '');
console.log(value);
类MSDN,然后我尝试将其转换为System.Object
。这可能在某些情况下有效,但在这种情况下却没有。将接收IWebElement
更改为IList
可解决投射异常。使用此代码运行,然后我发现调试器使用IList<Object>
列表中的代码的第一部分捕获所有数据。 Labels
仅返回null项。所以在我的案例中不需要第二步。