Paquete de agilidad HTML: uso de XPath para obtener un solo nodo: la referencia de objeto no está configurada para una instancia de un objeto

html-agility-pack xpath

Pregunta

este es mi primer intento de obtener un valor de elemento utilizando HAP. Recibo un error de objeto nulo cuando intento utilizar InnerText.

La URL que estoy raspando es: - http://www.mypivots.com/dailynotes/symbol/659/-1/e-mini-sp500-june-2013 Estoy tratando de obtener el valor de alta actual desde el Cambio de Día Tabla de resumen.

Mi código está en la parte inferior. En primer lugar, me gustaría saber si estoy haciendo esto de la manera correcta. Si es así, ¿es simplemente que mi valor de XPath es incorrecto?

el valor de XPath se obtuvo utilizando una utilidad que encontré llamada htmlagility helper. La versión firebug de la XPath a continuación, también da el mismo error: - / html / body / div [3] / div / table / tbody / tr [3] / td / table / tbody / tr [5] / td [3 ]

Mi código :-

WebClient myPivotsWC = new WebClient();
string nodeValue;
string htmlCode = myPivotsWC.DownloadString("http://www.mypivots.com/dailynotes/symbol/659/-1/e-mini-sp500-june-2013");
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(htmlCode);
HtmlNode node = doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[3]/div[1]/table[1]/tbody[1]/tr[3]/td[1]/table[1]/tbody[1]/tr[5]/td[3]");
nodeValue=(node.InnerText);

Gracias, Will.

Respuesta aceptada

No puede confiar en herramientas de desarrollo como FireBug o Chrome, etc ... para determinar el XPATH para los nodos que está buscando, ya que el XPATH proporcionado por dichas herramientas corresponde al DOM de HTML en la memoria mientras que el paquete de agilidad de HTML. Solo se conoce el código HTML devuelto por el servidor.

Lo que debe hacer es mirar visualmente lo que se envía (o simplemente hacer una fuente de vista). Verás que no hay ningún elemento TBODY por ejemplo. Así que quieres encontrar algo discriminante, y usar ejes XPATH, por ejemplo. Además, su XPATH, incluso si funcionara, no sería muy resistente a los cambios en el documento, por lo que necesita encontrar algo más "estable" para que el raspado sea más seguro para el futuro.

Aquí hay un código que parece funcionar:

HtmlNode node = doc.DocumentNode.SelectSingleNode("//td[@class='dnTableCell']//a[text()='High']/../../td[3]");

Esto es lo que hace:

  • encuentre un elemento TD con un atributo CLASS configurado en 'dnTableCell'. El token // significa que la búsqueda es recursiva en la jerarquía XML.
  • encuentre un elemento A que contenga un texto (texto interno) igual a 'Alto'.
  • navegar dos padres arriba (llegaremos al elemento TR más cercano)
  • seleccione el tercer elemento TD desde allí

Respuesta popular

Como explicó Simon Mourier , obtuviste el HTML en bruto enviado por el servidor. El elemento que necesita aún no se ha procesado, por lo que aún no puede recuperarlo porque no existe en el DOM. Una forma sencilla de solucionar este problema es utilizar un renderizador web para compilar el DOM, que puede capturar el HTML y rasparlo. Yo uso WatiN de esta manera:

WatiN.Core.Settings.MakeNewInstanceVisible = false;
WatiN.Core.Settings.AutoMoveMousePointerToTopLeft = false; 
IE ie = new IE();
ie.GoTo(urlLink); 
ie.WaitForComplete();
string html = ie.Html;
ie.close();


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué