Tag di analisi C # Html Agility Pack con più alternative

c# html html-agility-pack tags

Domanda

Non ho alcuna esperienza con HTML, quindi scusate qualsiasi terminologia errata.

Sto cercando di analizzare un documento HTML utilizzando l'HTML Agility Pack e sto cercando una stringa molto specifica.

Voglio ottenere tutte le stringhe della forma:

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

Quindi il mio parametro select è

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

Tuttavia, anche questo finisce per restituire stringhe come

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

Mi sembra (almeno per quanto ne so): il tag img viene cercato e src deve essere trovato solo sullo stesso livello, non necessariamente accanto al tag img.

Dopo aver esaminato la documentazione, sento che sto cercando di fare qualcosa che non sono autorizzato a svolgere con questa funzione.

Qualcuno può suggerire il modo corretto per farlo. Grazie!

Risposta accettata

" Il tag img viene cercato e src deve essere trovato solo sullo stesso livello, non necessariamente accanto al tag img . "

Sembra che tu voglia trovare l'elemento <img> dove gli attributi src è il primo attributo. Si noti che il parser XML / HTML non deve conservare l'ordine degli attributi, quindi in genere non si desidera selezionare l'elemento in base ad un determinato ordine di attributo, cioè dove l'attributo src viene prima, ecc.

In ogni caso, l'ordine degli attributi è stato conservato da HAP nel mio test Attributes[0].Name semplificato, quindi utilizzando Attributes[0].Name * per controllare che anche il nome del primo attributo funzionasse:

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

produzione :

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

*) Gli XPath già filtrano gli elementi img che hanno attributo src , quindi Attributes[0].Name non produrrebbe mai NRE, se sei preoccupato.


Risposta popolare

Non ho familiarità con XPATH, quindi presumo che il tuo sia corretto (di solito uso i selettori CSS utilizzando la libreria ScrapySharp oltre a HtmlAgilityPack).

Il seguente snippet di codice del progetto della console restituirà solo il nodo img che si desidera, ovvero quello con solo 2 attributi - src ed ecc., Non meno non di più. Carico manualmente un esempio di codice HTML con 3 nodi immagine, come il seguente:

        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



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché