C # Html Agility Pack analyse des balises avec plusieurs alternatives

c# html html-agility-pack tags

Question

Je n'ai aucune expérience en HTML, donc excusez toute terminologie incorrecte.

J'essaie d'analyser un document HTML à l'aide du HTML Agility Pack et je recherche une chaîne très spécifique.

Je veux obtenir toutes les chaînes de la forme:

<img src="..." etc=....">

Donc, mon paramètre de sélection est

HtmlNodeCollection images = doc.DocumentNode.SelectNodes("//img[@src]");

Cependant, cela finit également par renvoyer des chaînes telles que

<img width="..." src="..." etc="..">

Il me semble (du moins à ma connaissance): La balise img est recherchée et src doit uniquement être trouvé au même niveau, pas nécessairement juste à côté de la balise img.

Après avoir examiné la documentation, je sens que j'essaie de faire quelque chose que je ne suis pas autorisé à utiliser avec cette fonction.

Quelqu'un peut-il s'il vous plaît suggérer la bonne façon de faire cela. Merci!

Réponse acceptée

" La balise img est recherchée et src doit uniquement être trouvé au même niveau, pas nécessairement juste à côté de la balise img . "

Il semble que vous souhaitiez trouver un élément <img> où attributs src est le premier attribut. Notez que l’analyseur XML / HTML n’a pas à conserver l’ordre des attributs, vous ne voulez donc généralement pas sélectionner d’élément en fonction de cet ordre, c’est-à-dire où l’attribut src vient en premier, etc.

Quoi qu'il en soit, l'ordre des attributs a été préservé par HAP dans mon test simplifié, d'où l'utilisation d' Attributes[0].Name * pour vérifier le nom du premier attribut également utilisé:

var raw = @"<div>
    <img src=""..."" etc=""...."">
    <img width=""..."" src=""..."" etc="".."">
    <img>
</div>";
var doc = new HtmlDocument();
doc.LoadHtml(raw);
var result = doc.DocumentNode
                .SelectNodes("//img[@src]")
                .Where(o => o.Attributes[0].Name == "src")
                .ToList();
foreach (var item in result)
{
    Console.WriteLine(item.OuterHtml);
}

sortie:

<img src="..." etc="....">

*) Le XPath déjà filtre les éléments img qui ont l'attribut src , donc Attributes[0].Name ne produira jamais NRE, si vous êtes concerné.


Réponse populaire

Je ne suis pas familier avec XPATH, donc je suppose que le vôtre est correct (j’utilise habituellement des sélecteurs CSS utilisant la bibliothèque ScrapySharp en plus de HtmlAgilityPack).

L'extrait de code de projet de la console suivant renverra uniquement le nœud img souhaité, c'est-à-dire celui avec 2 attributs uniquement - src et etc., ni moins ni plus. Je charge manuellement un exemple HTML avec 3 noeuds d'image, comme suit:

        HtmlDocument doc = new HtmlDocument();
        string html = @"
            <img src='img1.jpg' />
            <img src='img1.jpg' etc='etcValue' />
            <img width='200px' src='img1.jpg' />
        ";
        doc.LoadHtml(html);

        var relevantImgNodes = doc.DocumentNode.SelectNodes("//img")
            .Where(n => 
                n.Attributes.Count == 2 && 
                !string.IsNullOrEmpty(n.GetAttributeValue("src")) && 
                !string.IsNullOrEmpty(n.GetAttributeValue("etc")));

        Console.WriteLine(relevantImgNodes.Count()); // prints 1



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