Sélectionner tous les liens d'une table HTML à l'aide de XPath (et HtmlAgilityPack)

c# html-agility-pack xpath

Question

Ce que j'essaie de faire est d'extraire tous les liens avec un attribut href commençant par http: //, https: // ou /. Ces liens se trouvent dans une table (tbody> tr> td etc.) avec une certaine classe. Je pensais pouvoir spécifier uniquement l'élément a sans le chemin d'accès complet, mais cela ne semble pas fonctionner. Je reçois une exception NullReferenceException à la ligne qui sélectionne les liens:

var table = doc.DocumentNode.SelectSingleNode("//table[@class='containerTable']");
if (table != null)
{
    foreach (HtmlNode item in table.SelectNodes("a[starts-with(@href, 'https://')]"))
    {
        //not working

Je ne connais aucune recommandation ni meilleure pratique concernant XPath. Est-ce que je crée une surcharge lorsque j'interroge le document deux fois?

Réponse acceptée

Utiliser :

 //tbody/descendant::a[starts-with(@href,'https://')
                     or
                       starts-with(@href,'http://')
                     or
                       starts-with(@href,'./') 
                      ]

Vous aurez toujours un problème , sauf si vous corrigez votre code pour tenir compte du fait que la méthode d'instance XmlNode.SelectNodes() a un type de retour XmlNodeList , pas HtmlNode .


Réponse populaire

Le problème est que vous sélectionnez la table, puis que vous essayez immédiatement de sélectionner les ancres comme si elles étaient des personnes décédées. Il y a des balises tr et td au milieu.

Donc, si vous modifiez votre chemin xpath comme suit, les choses devraient fonctionner:

"tbody/tr/td/a[starts-with(@href, 'https://')]"

Cela ne fonctionnera pas si vos ancres sont encapsulées dans autre chose. Vous pouvez donc sélectionner toutes les ancres du groupe de nœuds actuel (c.-à-d. La table):

"//a[starts-with(@href, 'https://')]"

Voir ceci pour plus de détails sur la syntaxe xpath.



Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow