【问题标题】:WebDriver can find element using xpath, Html Agility Pack cannotWebDriver 可以使用 xpath 找到元素,Html Agility Pack 不能
【发布时间】:2011-09-01 22:27:10
【问题描述】:

我一直在使用 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 更改为可行的://input[@name='q'],但这只会解决这个问题具体的例子,这不是重点,我需要一些能够完全或至少密切反映 WebDriver 的 xpath 引擎,甚至是 FirePath 或 FireFinder 的行为的东西 -火狐浏览器。

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

【问题讨论】:

  • 我在使用 Html Agility Pack 的 XPath 解析器方面取得了很好的成功,所以我想知道 XPath 是否不是最理想的。这是一个在生产应用程序中适用于我的示例:.//div[@id=\"main\"]//div[@id=\"content\"]//div[@id=\"title\"]
  • 不幸的是,大多数时候我不是创建 XPath 表达式的人。我帮助管理我们的自定义 WebDriver 框架,因此如果 QA 中的某个人创建了一个在 WebDriver 中工作的 XPath 表达式,它也必须在 Html Agility Pack 中工作。上面的示例只是为了捕捉我们一直遇到的一个常见问题。

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


【解决方案1】:

您遇到的问题是 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");

【讨论】:

  • 太棒了!我敢打赌,如果我查看以前有问题的 XPath 表达式,我会发现表单节点是它的根本原因。
猜你喜欢
  • 2011-04-14
  • 2015-08-31
  • 2019-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
  • 2014-07-13
相关资源
最近更新 更多