HTML Agility Pack - utilisation de XPath pour obtenir un seul nœud - Référence d'objet non définie sur une instance d'objet

html-agility-pack xpath

Question

C'est ma première tentative pour obtenir une valeur d'élément en utilisant HAP. Je reçois une erreur d'objet null lorsque j'essaie d'utiliser InnerText.

l'URL que je suis en train de gratter est: - http://www.mypivots.com/dailynotes/symbol/659/-1/e-mini-sp500-june-2013 J'essaie d'obtenir la valeur du plus haut courant du changement de jour Sommaire.

Mon code est en bas. Tout d’abord, je voudrais juste savoir si j’agis de la bonne façon? Si oui, est-ce simplement que ma valeur XPath est incorrecte?

la valeur XPath a été obtenue à l'aide d'un utilitaire que j'ai trouvé, appelé htmlagility helper. La version firebug du XPath ci-dessous donne également la même erreur: - / html / body / div [3] / div / table / tbody / tr [3] / td / table / tbody / tr [5] / td [3 ]

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

Merci, Will.

Réponse acceptée

Vous ne pouvez pas compter sur des outils de développement tels que FireBug ou Chrome, etc. pour déterminer le XPATH des noeuds recherchés, car le XPATH fourni par ces outils correspond au DOM HTML en mémoire tandis que le Pack d'agilité HTML ne connaît que le code HTML brut renvoyé par le serveur.

Ce que vous devez faire, c'est regarder visuellement ce qui est renvoyé (ou simplement faire une source de vue). Vous verrez qu'il n'y a pas d'élément TBODY par exemple. Donc, vous voulez trouver quelque chose de discriminant et utiliser les axes XPATH par exemple. En outre, votre XPATH, même s'il fonctionnait, ne résisterait pas beaucoup aux modifications apportées au document. Vous devez donc trouver quelque chose de plus "stable" pour que le grattage soit plus sûr.

Voici un code qui semble fonctionner:

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

C'est ce que ça fait:

  • trouver un élément TD avec un attribut CLASS défini sur 'dnTableCell'. Le jeton // signifie que la recherche est récursive dans la hiérarchie XML.
  • trouver un élément A qui contient un texte (texte intérieur) est égal à "Élevé".
  • naviguer deux parents vers le haut (nous allons arriver à l'élément TR le plus proche)
  • sélectionnez le 3ème élément TD à partir de là

Réponse populaire

comme Simon Mourier , vous avez obtenu le code HTML brut envoyé par le serveur. L'élément dont vous avez besoin n'a pas encore été rendu. Par conséquent, vous ne pouvez pas le récupérer car il n'existe pas dans le DOM. Un moyen simple de contourner ce problème consiste à utiliser un moteur de rendu Web pour construire le DOM, puis à récupérer le code HTML et à le supprimer. J'utilise WatiN comme ceci:

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



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi