2010-02-11 17 views
36

Im trabajando en un pequeño proyecto de hobby. Ya he escrito el código para obtener una URL, descargo el encabezado y devuelvo el tipo de tipo/contenido de mimo.Obtenga todos los enlaces en la página html?

Sin embargo, el paso antes de que este es el im pegado en - i necesidad de recuperar el contenido de todas las URL de la página de base dentro de una etiqueta, y entre comillas es decir

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

encontraría el favicon enlazar.

¿Hay algo de ayuda en la biblioteca .net o va a ser necesario para regex?

+11

Estoy recibiendo una sensación extraña que la agilidad del paquete de HTML es el camino a seguir ... – jball

Respuesta

54

Miraría usar el Html Agility Pack.

He aquí un ejemplo directamente desde su página de ejemplos sobre cómo encontrar todos los enlaces en una página:

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

} 
+0

XPath-ey - me gusta ¡eso! – maxp

+4

'DocumentElement' debe reemplazarse con' DocumentNode' – HadiRj

+0

Solo quería agregar que si el sitio que está intentando cargar tiene alguna compresión gzip, arrojará una excepción sobre 'hw.Load':' "'gzip' no es un nombre de codificación compatible. Para obtener información sobre cómo definir una codificación personalizada, consulte la documentación del método Encoding.RegisterProvider. Encontró una solución [aquí] (https://stackoverflow.com/a/36220920/6178243) –

14

no hay nada integrado en el BCL, pero afortunadamente se puede utilizar el HTML Agility Pack de lograr esto tarea bastante simple.

cuanto a su problema específico, consulte 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

Esto se puede hacer mucho más simplemente usando LINQ. – SLaks

+5

No estoy de acuerdo con que un enfoque basado en LINQ sea más simple. ¿Declarativo? Sí. ¿Funcional? ¿Absolutamente más simple? No, ambas soluciones son iguales en su simplicidad –

+0

XPath debería usar menos memoria –

31

Es necesario utilizar el HTML Agility Pack.

Por ejemplo:

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)); 
Cuestiones relacionadas