0

我在我的 C# 项目中使用 Ghost Driver (PhantomJS)。我有个问题。Selenium 有 PhantomJSWebElement 和 PhantomJSDriver。我正在创建 PhantomJSDriver

PhantomJSDriverService service = PhantomJSDriverService.CreateDefaultService();
service.IgnoreSslErrors = true;
service.LoadImages = false;
service.Start();
PhantomJSDriver ghostDriver = new PhantomJSDriver(service);

然后尝试通过 xpath 查找元素

List<string> retVal = new List<string>();
var aElements = ghostDriver.FindElementsByXPath("//div[@id='menu']//a[@href]");
foreach(PhantomJSWebElement link in aElements)
{
   try
   {
      retVal.Add(link.GetAttribute("href"));
   }
   catch (Exception)
   {
      continue;
   }
}

所以我在投射IWebElemetPhantomJSWebElement.

PhantomJSWebElement el = (PhantomJSWebElement)link; 

也不起作用(抛出铸造异常)。所以问题是,如何通过 PhantomJSDriver 获取 PhantomJSWebElement 在查找时只返回 IWebElement (或它们的集合)。

4

1 回答 1

0

通常,在使用 .NET 绑定时不应使用特定于浏览器的类。相反,您应该对您期望的接口进行编码。这允许您根据需要替换不同的实现。您的代码将如下所示:

PhantomJSDriverService service = PhantomJSDriverService.CreateDefaultService();
service.IgnoreSslErrors = true;
service.LoadImages = false;

// Not sure I'd use Start here. The constructor will start the service
// for you.
service.Start();

// Use the IWebDriver interface. There's no real advantage to using
// the PhantomJSDriver class.
IWebDriver ghostDriver = new PhantomJSDriver(service);

// ...

List<string> retVal = new List<string>();
var aElements = ghostDriver.FindElements(By.XPath("//div[@id='menu']//a[@href]"));

// Use the IWebElement interface here. The concrete PhantomJSWebElement
// implementation gives you no advantages over coding to the interface.
foreach(IWebElement link in aElements)
{
    try
    {
        retVal.Add(link.GetAttribute("href"));
    }
    catch (Exception)
    {
        continue;
    }
}

您还应该注意,类文档很可能不正确。了解语言绑定的源代码后,PhantomJSWebElement该类从未在任何地方实际实例化。我相信您实际上从FindElements()调用中得到的是RemoteWebElements,因此尝试将它们从继承层次结构中转换为更具体的子类注定要失败。

于 2014-01-15T02:12:34.497 回答