es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo obtener todos los hipervínculos de Wikipedia desde una página web utilizando HttpClient en C#.

Quiero obtener todos los hyperlinks de la página de Wikipedia que llevan a otra página de Wikipedia en C#.
Por ejemplo:

En la captura de pantalla de arriba, puedes ver que solo quiero obtener los enlaces que llevan a otro artículo de Wiki (rectángulos rojos), aunque haya otros enlaces en la página. He escrito una función que raspa cada enlace de la página y devuelve un HashSet de ellos, su cuerpo es el siguiente:

private async Task<HashSet<string>> GetPages(CrawlerPage page)
{
    var client = new HttpClient();
    client.DefaultRequestHeaders.Add("User-Agent", "Programa de consola C#");
    var htmlContent = await client.GetStringAsync(page.mainLink);

    HtmlDocument htmlDoc = new HtmlDocument();
    htmlDoc.LoadHtml(htmlContent);
    var programmerLinks = htmlDoc.DocumentNode
        .Descendants("li")
        .Where(node => !node.GetAttributeValue("class", "").Contains("tocsection")).ToList();

    HashSet<string> wikiLinks = new();

    foreach (var link in programmerLinks)
    {
        if (link.FirstChild.Attributes.Count > 0)
            wikiLinks.Add("https://en.wikipedia.org/" + link.FirstChild.Attributes[0].Value);
    }

    return wikiLinks;
}

La función funciona bien, pero raspa todo. Mira la captura de pantalla a continuación:

Puedes ver que las cosas en los rectángulos rojos son los enlaces que quiero obtener, el resto es basura (enlaces que no necesito).

Me di cuenta de que todos estos enlaces están debajo de la etiqueta “ en HTML, y los enlaces están en <a href="">, pero aún no logro entender cómo obtener estos enlaces concretos.

¿Puedes decirme cómo puedo obtener estos enlaces deseados?

¡Gracias!

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para obtener solo los hipervínculos que llevan a otra página de Wikipedia, puedes modificar el código existente para filtrar los enlaces que no contengan la cadena “/wiki/” en el atributo href. Aquí está la función modificada:

    private async Task<><string>> ObtenerEnlacesWiki(CrawlerPage pagina)
    {
        var cliente = new HttpClient();
        cliente.DefaultRequestHeaders.Add("User-Agent", "Programa de consola C#");
        var contenidoHTML = await cliente.GetStringAsync(pagina.enlacePrincipal);
    
        HtmlDocument htmlDoc = new HtmlDocument();
        htmlDoc.LoadHtml(contenidoHTML);
    
        HashSet<string> enlacesWiki = new HashSet<string>();
    
        var nodosEnlacesWiki = htmlDoc.DocumentNode.Descendants("p")
            .SelectMany(p => p.Descendants("a"))
            .Where(a => a.GetAttributeValue("href", "").Contains("/wiki/") &&
                        !a.GetAttributeValue("href", "").Contains(":"));
    
        foreach (var enlace in nodosEnlacesWiki)
        {
            enlacesWiki.Add("https://es.wikipedia.org" + enlace.GetAttributeValue("href", ""));
        }
    
        return enlacesWiki;
    }
    

    La variable nodosEnlacesWiki utiliza LINQ para seleccionar solo los nodos <a> que tienen un atributo href que contiene “/wiki/” y no contienen dos puntos (para excluir enlaces como “mailto:”). El HashSet resultante solo contiene los enlaces que cumplen con estos criterios.

Comments are closed.