WebDriver peut rechercher un élément à l’aide de xpath, le Pack Agility HTML ne

c# html-agility-pack visual-studio-2010 webdriver xpath

Question

J'ai toujours eu des problèmes avec Html Agility Pack; mes requêtes XPath ne fonctionnent que lorsqu'elles sont extrêmement simples:

//*[@id='some_id']

ou

//input

Cependant, chaque fois que cela devient plus compliqué, Html Agility Pack ne peut pas le gérer. Voici un exemple illustrant le problème. J'utilise WebDriver pour accéder à Google et renvoie le code source, qui est transmis à Html Agility Pack. WebDriver et HtmlAgilityPack tentent tous deux de localiser l'élément / noeud (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();

Dans ce cas, WebDriver a réussi à localiser l'élément, contrairement à HTML Agility Pack.

Je sais, je sais, dans ce cas, il est très facile de changer le xpath en un chemin qui fonctionnera: // input [@ name = 'q'] , mais cela ne résoudra que cet exemple spécifique, qui n'est pas le point, Je besoin de quelque chose qui exactement ou au moins refléter étroitement le comportement du moteur XPath de WebDriver, ou même le FirePath ou FireFinder add-ons Firefox.

Si WebDriver peut le trouver, alors pourquoi le Pack d'agilité HTML ne le trouve-t-il pas aussi?

Réponse acceptée

Le problème que vous rencontrez concerne l'élément FORM. HTML Agility Pack traite cet élément différemment - par défaut, il ne signalera jamais qu'il a des enfants.

Dans l'exemple particulier que vous avez donné, cette requête trouve l'élément cible:

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

Cependant, ce n'est pas le cas, il est donc clair que l'élément de formulaire déclenche l'analyseur:

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

Ce comportement est configurable, cependant. Si vous placez cette ligne avant d'analyser le code HTML, le formulaire vous donnera des nœuds enfants:

HtmlNode.ElementsFlags.Remove("form");


Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow