HTML Agility Pack - utilizzando XPath per ottenere un singolo nodo - Riferimento oggetto non impostato su un'istanza di un oggetto

html-agility-pack xpath

Domanda

questo è il mio primo tentativo di ottenere un valore di elemento usando HAP. Ricevo un errore oggetto nullo quando provo ad usare InnerText.

l'URL che sto scrivendo è: - http://www.mypivots.com/dailynotes/symbol/659/-1/e-mini-sp500-june-2013 Sto cercando di ottenere il valore per il massimo attuale dal giorno Cambia Tabella riassuntiva.

Il mio codice è in fondo. In primo luogo, vorrei solo sapere se sto andando su questo nel modo giusto? Se è così, allora è semplicemente che il mio valore XPath non è corretto?

il valore XPath è stato ottenuto utilizzando un programma di utilità che ho trovato chiamato helper htmlagility. La versione firebug di XPath qui sotto, dà anche lo stesso errore: - / html / body / div [3] / div / table / tbody / tr [3] / td / table / tbody / tr [5] / td [3 ]

Il mio codice: -

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);

Grazie, Will.

Risposta accettata

Non puoi fare affidamento su strumenti di sviluppo come FireBug o Chrome, ecc ... per determinare l'XPATH per i nodi che stai cercando, poiché l'XPATH fornito da tali strumenti corrisponde al DOM HTML in memoria mentre il pacchetto agilità Html conosce solo l'HTML non elaborato inviato dal server.

Quello che devi fare è guardare visivamente ciò che viene inviato indietro (o semplicemente fare una vista). Vedrai che non esiste un elemento TBODY ad esempio. Quindi vuoi trovare qualcosa di discriminante e usa gli assi XPATH per esempio. Inoltre, il tuo XPATH, anche se funzionasse, non sarebbe molto resistente ai cambiamenti nel documento, quindi devi trovare qualcosa di più "stabile" per lo scraping per essere più a prova di futuro.

Ecco un codice che sembra funzionare:

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

Questo è quello che fa:

  • trova un elemento TD con un attributo CLASS impostato su 'dnTableCell'. // token indica che la ricerca è ricorsiva nella gerarchia XML.
  • trova un elemento A che contiene un testo (testo interno) uguale a "Alto".
  • avvicinare due genitori (arriveremo all'elemento TR più vicino)
  • seleziona il terzo elemento TD da lì

Risposta popolare

come la spiegazione di Simon Mourier , hai ottenuto l'HTML non elaborato inviato dal server. L'elemento di cui hai bisogno non è ancora stato reso, quindi non puoi ancora recuperarlo perché non esiste nel DOM. una semplice soluzione a questo problema è usare un renderer web per costruire il DOM, che puoi afferrare l'HTML e scriverlo. Io uso WatiN in questo modo:

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();



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché