WebDriver可以使用xpath找到元素,Html Agility Pack不能

时间:2011-05-25 16:30:44

标签: c# visual-studio-2010 xpath html-agility-pack webdriver

我一直遇到Html Agility Pack的问题;我的XPath查询只有在非常简单时才能工作:

//*[@id='some_id']

//input

但是,只要它们变得更复杂,那么Html Agility Pack就无法处理它。 这是一个演示问题的示例,我使用WebDriver导航到Google,并返回页面源,传递给Html Agility Pack,WebDriver和HtmlAgilityPack都尝试定位元素/节点(C#):

//The XPath query
const string xpath = "//form//tr[1]/td[1]//input[@name='q']";

//Navigate to Google and get page source
var driver = new FirefoxDriver(new FirefoxProfile()) { Url = "http://www.google.com" };
Thread.Sleep(2000);

//Can WebDriver find it?
var e = driver.FindElementByXPath(xpath);
Console.WriteLine(e!=null ? "Webdriver success" : "Webdriver failure");

//Can Html Agility Pack find it?
var source = driver.PageSource;
var htmlDoc = new HtmlDocument { OptionFixNestedTags = true };
htmlDoc.LoadHtml(source);
var nodes = htmlDoc.DocumentNode.SelectNodes(xpath);
Console.WriteLine(nodes!=null ? "Html Agility Pack success" : "Html Agility Pack failure");

driver.Quit();

在这种情况下,WebDriver成功找到了该项目,但Html Agility Pack没有。

我知道,我知道,在这种情况下,将xpath更改为可以正常工作的路径非常容易: //输入[@ name ='q'] ,但这只会修复此问题具体的例子,这不是重点,我需要的东西完全或至少密切反映WebDriver的xpath引擎的行为,甚至FirePath或FireFinder添加 - 对Firefox的影响。

如果WebDriver可以找到它,那么为什么Html Agility Pack也找不到呢?

1 个答案:

答案 0 :(得分:8)

您遇到的问题是使用FORM元素。 HTML Agility Pack handles that element differently - 默认情况下,它永远不会报告它有子项。

在您提供的特定示例中,此查询确实找到了目标元素:

.//div/div[2]/table/tr/td/table/tr/td/div/table/tr/td/div/div[2]/input

然而,这不是,所以很明显表单元素正在绊倒解析器:

.//form/div/div[2]/table/tr/td/table/tr/td/div/table/tr/td/div/div[2]/input

但这种行为是可配置的。如果在解析HTML之前放置此行,表单将为您提供子节点:

HtmlNode.ElementsFlags.Remove("form");