Analyser HTML à l'aide de HTMLAgilityPack

c# html-agility-pack

Question

J'essaie d'analyser le code HTML suivant à l'aide du pack d'agilité HTML.

Ceci est un extrait du fichier entier renvoyé par le code:

<div class="story-body fnt-13 p20-b user-gen">
    <p>text here text here text </p>
    <p>text here text here text text here text here text text here text here text text here text here text </p>
    <div  class="gallery clr bdr aln-c js-no-shadow mod  cld">
        <div>
            <ol>
                <li class="fader-item aln-c ">
                    <div class="imageWrap m10-b">
                       &#8203;<img class="http://www.domain.com/picture.png| " src="http://www.domain.com/picture.png" alt="alt text" />
                    </div>
                    <p class="caption">caption text</p>
                </li>
            </ol>
        </div>
    </div >
    <p>text here text here text text here text here text text here text here text text here text here text </p>
    <p>text here text here text text here text here text text here text here text text here text here text text here text here text </p>
    <p>text here text here text text here text here text text here text here text text here text here text text here text here text </p>
</div>

Je reçois cet extrait de code en utilisant ce qui suit (ce qui est désordonné, je sais)

string url = "http://www.domain.com/story.html";
var webGet = new HtmlWeb();
var document = webGet.Load(url);

var links = document.DocumentNode
        .Descendants("div")
        .Where(div => div.GetAttributeValue("class", "").Contains("story-body fnt-13 p20-b user-gen")) //
        .SelectMany(div => div.Descendants("p"))
        .ToList();
int cn = links.Count;

HtmlAgilityPack.HtmlNodeCollection tl = document.DocumentNode.SelectNodes("/html[1]/body[1]/div[1]/div[2]/div[1]/div[1]/div[1]/div[2]/div[1]");
foreach (HtmlAgilityPack.HtmlNode node in tl)
{
    textBox1.AppendText(node.InnerText.Trim());
    textBox1.AppendText(System.Environment.NewLine);
}

Le code parcourt chaque p et (pour l'instant) l'ajoute à une zone de texte. Tout fonctionne correctement, à l'exception de la balise div avec la gallery clr bdr aln-c js-no-shadow mod cld classe gallery clr bdr aln-c js-no-shadow mod cld . Le résultat de ce morceau de HTML est que je reçois le &#8203; et légende bits de texte.

Quel est le meilleur moyen d'omettre cela des résultats?

Réponse acceptée

XPATH est votre ami. Essayez ceci et oubliez cette syntaxe minable de xlink :-)

HtmlNodeCollection tl = document.DocumentNode.SelectNodes("//p[not(@*)]");
foreach (HtmlAgilityPack.HtmlNode node in tl)
{
    Console.WriteLine(node.InnerText.Trim());
}

Cette expression sélectionnera tous les P nœuds pour lesquels aucun attribut n'est défini. Voir ici pour d'autres exemples: Syntaxe XPath


Réponse populaire

Ce que vous demandez n'est pas tout à fait clair. Je pense que vous demandez comment obtenir uniquement les descendants directs d'une div. Si c'est le cas, utilisez ChildNodes plutôt que Descendants . C'est:

.SelectMany(div => div.ChildNodes().Where(n => n.Name == "p"))

Le problème est que Descendants effectue une marche entièrement récursive de l'arborescence de documents.



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