Introduction
De nombreuses personnes connaissent déjà HTML Agility Pack (HAP), un composant gratuit fort pratique développé par Simon Mourier (ancien consultant architecte chez Microsoft aujourd'hui directeur technique de SoftFluent), qui simplifie réellement votre vie quant à la manipulation de contenu HTML.
Qu'est-ce que HAP ?
HAP est un parser HTML qui construit un modèle objet de document (DOM) en lecture/écriture qui supporte XPATH ou XSLT. C'est un assemblage .NET qui vous permet de « parser » directement des fichiers HTML du Web. Le parser est très tolérant avec le HTML malformé qu'on retrouve dans la "vraie vie". Le modèle objet est très similaire à celui de System.Xml, mais pour des documents HTML (ou des streams).
Cet article démontre la facilité avec laquelle on peut télécharger des images depuis n'importe quel site web public et les stocker dans un répertoire local. On peut également trouver 3 autres exemples dans la version téléchargeable de HAP.
Le scénario
Problème
Mido, un graphiste qui possède quelques compétences de développement, doit souvent télécharger des quantités importantes d'images depuis le Web. Comme il en a quelque peu assez de cliquer sur chaque image pour la sauvegarder dans son répertoire local, il décide de développer son propre récupérateur d'images. Mais très vite, il rencontre un problème majeur : comment traiter les flux HTML reçus des sites web (sachant que ceux-ci sont souvent malformés) de façon à identifier les chaînes correctes contenant les liens vers les images qu'il veut télécharger ? Il pourrait écrire du code RegEx un peu amusant (ou déplaisant suivant le point de vue que l'on prend J) mais il existe une solution plus aisée : HTML Agility Pack.
Solution
Après avoir effectué quelques recherches sur le réseau, Mido trouve enfin le composant HTML Agility Pack. Il décide rapidement de baser son développement sur HAP. Voici l'allure du code en utilisant ce composant (code source complet téléchargeable chez SoftFluent sur le lien mentionné en bas de cet article) :
- Instanciation de la classe HtmlWeb (une classe utilitaire pour récupérer le document HTML depuis HTTP):
HtmlWeb hw = new HtmlWeb();
Connexion à l'URL de départ avec la méthode Load qui retourne un objet HtmlDocument :
HtmlDocument doc = hw.Load(remoteUrl);
- Extraction des liens vers les images pour être téléchargées : nous avons décidé de créer une méthode GetLinks pour davantage de clarté, cette méthode sélectionnant à l'aide d'une requête XPATH toutes les chaînes débutant par "a href" et retournant un objet StringCollection contenant les URLs complets vers les images distantes à télécharger :
HtmlNodeCollection atts = doc.DocumentNode.SelectNodes("//a[starts-with(@href, '/')]");
Important: c'est ici que l'on voit que HAP est très puissant; il permet la sélection de n'importe quelle partie d'un document HTML à l'aide d'une requête XPATH.
- Téléchargement de chaque fichier en utilisant la classe System.Net.WebClient :
static void DownloadPictures(StringCollection sc, string destination)
{
WebClient myWebClient = new WebClient();
myWebClient.Credentials = CredentialCache.DefaultCredentials;
foreach (String filePath in sc)
{
Uri uri = new Uri(filePath);
int length = uri.Segments.Length;
string fileName = uri.Segments[length - 1];
if (!System.IO.File.Exists(destination + HttpUtility.UrlDecode(fileName)))
{
myWebClient.DownloadFile(HttpUtility.UrlPathEncode(filePath), destination + fileName);
Console.WriteLine("File {0} has been downloaded.",
HttpUtility.UrlDecode(fileName));
}
}
}
Un autre exemple d'application
Si vous souhaitez télécharger automatiquement tous les fichiers de la PDC, utilisez l'exemple en remplaçant l'URL initial par http://commnet.microsoftpdc.com/content/downloads.aspx et les extensions des fichiers par "ppt" et "doc" au lieu de "gif" et "jpg". Vous verrez que tout cela reste très simple :).
Conclusion
Html Agility Pack est un outil très puissant qui vous aidera à naviguer à l'intérieur de n'importe quel flux HTML avec la même souplesse que vous pouvez le faire avec des fichiers XML. Cela vous permet de construire de nouvelles applications (Service Web, site web, etc.) en encapsulant l'application HTML source. Par exemple, vous pouvez créer un proxy RSS pour n'importe quel site Web afin qu'un lecteur RSS puisse syndiquer le contenu de sites web non RSS. L'exemple RSS se trouve dans l'archive Zip.
Télécharger le code d'exemple
Omid Bayani & Simon Mourier |