2010-02-11 18 views
36

Sto lavorando su un piccolo progetto per hobby. Ho già scritto il codice per ottenere un URL, scaricare l'intestazione e restituire il tipo MIME/tipo di contenuto.Ottieni tutti i link sulla pagina html?

Tuttavia, il passo prima di questo è quello im bloccato su - ho bisogno di recuperare il contenuto di tutti gli URL sulla pagina in base all'interno di un tag, e tra virgolette IE

... 
<link rel='shortcut icon' href="/static/favicon.ico" type="image/x-icon" /> 
... 

avrebbe trovato la favicon collegamento.

C'è qualcosa di utile nella libreria .net o si tratta di un caso per regex?

+11

sto ottenendo una strana sensazione che il codice HTML Agility Pack è la strada da percorrere ... – jball

risposta

54

Guarderei usando lo Html Agility Pack.

Ecco un esempio direttamente dalla loro pagina esempi su come trovare tutti i link in una pagina:

HtmlWeb hw = new HtmlWeb(); 
HtmlDocument doc = hw.Load(/* url */); 
foreach(HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]")) 
{ 

} 
+0

xpath-ey - mi piace esso! – maxp

+4

'DocumentElement' deve essere sostituito con' DocumentNode' – HadiRj

+0

Volevo solo aggiungere che se il sito che stai tentando di caricare ha qualche compressione gzip, genererà un'eccezione su 'hw.Load':' "'gzip' non è un nome di codifica supportato Per informazioni sulla definizione di una codifica personalizzata, consultare la documentazione per il metodo Encoding.RegisterProvider. Trovato un trucco [qui] (https://stackoverflow.com/a/36220920/6178243) –

14

non c'è nulla integrato nel BCL, ma per fortuna è possibile utilizzare il HTML Agility Pack per raggiungere questo obiettivo compito abbastanza semplicemente.

quanto riguarda il tuo problema specifico, vedere Easily extracting links from a snippet of html with HtmlAgilityPack:

private List<string> ExtractAllAHrefTags(HtmlDocument htmlSnippet) 
{ 
    List<string> hrefTags = new List<string>(); 

    foreach (HtmlNode link in htmlSnippet.DocumentNode.SelectNodes("//a[@href]")) 
    { 
     HtmlAttribute att = link.Attributes["href"]; 
     hrefTags.Add(att.Value); 
    } 

    return hrefTags; 
} 
+2

Questo può essere fatto molto più semplicemente usando LINQ – SLaks

+5

Non sono d'accordo sul fatto che un approccio basato su LINQ sia più semplice Dichiarativo Sì Sì Funzionante Assolutamente Semplificato No, entrambe le soluzioni sono uguali nella loro semplicità –

+0

XPath dovrebbe usare meno memoria –

31

È necessario utilizzare il HTML Agility Pack.

Ad esempio:

var doc = new HtmlWeb().Load(url); 
var linkTags = doc.DocumentNode.Descendants("link"); 
var linkedPages = doc.DocumentNode.Descendants("a") 
            .Select(a => a.GetAttributeValue("href", null)) 
            .Where(u => !String.IsNullOrEmpty(u));