WebDriver puede encontrar elementos utilizando xpath, Html Agility Pack no puede

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

Pregunta

Siempre he tenido problemas con Html Agility Pack; Mis consultas XPath solo funcionan cuando son extremadamente simples:

//*[@id='some_id']

o

//input

Sin embargo, cada vez que se vuelven más complicados, entonces Html Agility Pack no puede manejarlo. Aquí hay un ejemplo que demuestra el problema, estoy usando WebDriver para navegar a Google y devolver el origen de la página, que se pasa a Html Agility Pack, y tanto WebDriver como HtmlAgilityPack intentan localizar el elemento / nodo (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();

En este caso, WebDriver localizó con éxito el elemento, pero Html Agility Pack no lo hizo.

Lo sé, lo sé, en este caso es muy fácil cambiar el xpath a uno que funcione: // ingrese [@ name = 'q'] , pero eso solo solucionará este ejemplo específico, que no es el punto, Necesito algo que exactamente o al menos refleje estrechamente el comportamiento del motor xpath de WebDriver, o incluso los complementos de FirePath o FireFinder para Firefox.

Si WebDriver puede encontrarlo, ¿por qué no puede encontrarlo también Html Agility Pack?

Respuesta aceptada

El problema que estás encontrando es con el elemento FORM. HTML Agility Pack maneja ese elemento de manera diferente ; de manera predeterminada, nunca informará que tiene hijos.

En el ejemplo particular que dio, esta consulta encuentra el elemento de destino:

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

Sin embargo, esto no es así, por lo que está claro que el elemento de formulario está activando el analizador:

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

Ese comportamiento es configurable, sin embargo. Si coloca esta línea antes de analizar el HTML, el formulario le dará nodos secundarios:

HtmlNode.ElementsFlags.Remove("form");


Related

Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow