Selenium webdriver系统无效的Cast异常

时间:2015-05-24 18:22:14

标签: c# selenium

为了在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结构中,我就能找到我需要的数字。

2 个答案:

答案 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项。所以在我的案例中不需要第二步。