HTML Agility Pack - Verwenden von XPath zum Abrufen eines einzelnen Knotens - Objektreferenz wird nicht auf eine Instanz eines Objekts festgelegt

html-agility-pack xpath

Frage

Dies ist mein erster Versuch, einen Elementwert mithilfe von HAP zu erhalten. Ich erhalte einen Null-Objektfehler, wenn ich versuche, InnerText zu verwenden.

die URL, die ich scraping ist: - http://www.mypivots.com/dailynotes/symbol/659/-1/e-mini-sp500-june-2013 Ich versuche, den Wert für das aktuelle Hoch von der Tagesänderung zu erhalten Übersichtstabelle.

Mein Code ist am unteren Rand. Erstens möchte ich nur wissen, ob ich das richtig mache. Wenn ja, ist mein XPath-Wert dann einfach falsch?

Der XPath-Wert wurde mit einem Dienstprogramm namens htmlagility helper abgerufen. Die Firebug-Version des XPath unten, gibt auch den gleichen Fehler: - / html / body / div [3] / div / Tabelle / tbody / tr [3] / td / Tabelle / tbody / tr [5] / td [3 ]

Mein Code: -

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

Danke, Will.

Akzeptierte Antwort

Sie können sich nicht auf Entwicklertools wie FireBug oder Chrome usw. verlassen, um XPATH für die Knoten zu ermitteln, nach denen Sie suchen, da die XPATH von solchen Tools dem HTML-DOM im Speicher und dem Html Agility Pack entsprechen weiß nur über das rohe HTML, das vom Server zurückgesendet wird.

Was Sie tun müssen, ist visuell zu sehen, was zurückgeschickt wird (oder einfach eine Ansichtsquelle). Sie werden sehen, dass zum Beispiel kein TBODY-Element vorhanden ist. Sie wollen also etwas Diskriminierendes finden und zum Beispiel XPATH-Achsen verwenden . Auch wenn Ihr XPATH, selbst wenn es funktionierte, nicht sehr resistent gegen Änderungen im Dokument wäre, müssen Sie etwas "stabiler" für das Scraping finden, um zukunftssicherer zu sein.

Hier ist ein Code, der zu funktionieren scheint:

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

Das ist was es tut:

  • Suchen Sie ein TD-Element mit einem CLASS-Attribut, das auf 'dnTableCell' gesetzt ist. Das // Token bedeutet, dass die Suche in der XML-Hierarchie rekursiv ist.
  • finde ein A-Element, das einen Text (innerer Text) enthält, der gleich "High" ist.
  • navigiere zwei Eltern nach oben (wir kommen zum nächsten TR-Element)
  • Wählen Sie das 3. TD-Element von dort

Beliebte Antwort

Wie Simon Mourier erklärt, haben Sie das rohe HTML erhalten, das vom Server gesendet wurde. Das von Ihnen benötigte Element wurde noch nicht gerendert. Sie können es noch nicht abrufen, da es im DOM nicht existiert. Eine einfache Lösung für dieses Problem besteht darin, einen Web-Renderer zum Erstellen des DOM zu verwenden, dann können Sie den HTML-Code abrufen und ihn abkratzen. Ich benutze WatiN so:

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


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum