Télécharger le contenu d'une page WEB distante

Décembre 2016



Introduction


Il n'existe pas, dans la librairie standard, de fonction permettant de télécharger une page web, et même pour être plus général, de fonctions pour communiquer en utilisant le protocole HTTP.

Il n'existe finalement que deux manières:
  • Utiliser les fonctions de communications bas niveau: les sockets pour reproduire le dialogue HTTP.
  • Utiliser une librairie capable de faire ça toute seule, ce qui vous permettra de vous concentrer sur l'essentiel.


LibCurl est une de ces librairies qui supporte également beaucoup d'autres protocoles comme ftp, ldap etc... C'est également une librairie libre et portable (passe indifféremment sous Windows comme Unix par exemple).

Installation sous Linux (Ubuntu / Debian)


Ouvrez un shell puis tapez:
sudo apt-get install libcurl3 libcurl3-dev

Voilà, vous avez installé la librairie et ses fichiers d'en-têtes.

Installation sous Windows


Dev C++


Ceci a été testé avec la version 4.9.9.2 uniquement.

Avec l'IDE libre Dev C++, l'installation est plutôt simple, aussi je vous recommande ce logiciel dans notre exemple d'autant plus qu'il est gratuit et libre.
Nous allons installer d'abord la librairie zlib, dont dépend libcurl, puisque nous installerons libcurl ensuite.

Ouvrez donc Dev C++ et allez dans le menu Outils/Nouvelles versions Packages.
Dans le menu déroulant intitulé "Select devpack server" en haut de la petite fenêtre de gestion de package, sélectionnez devpacks.org puis cliquez sur le bouton "Check for updates".



Des noms de bibliothèques vont apparaître, cherchez "zlib" et sélectionnez la dernière version.

Cliquez sur "Download selected" et laissez vous guider par l'installeur.



Ensuite, dans la même liste, cherchez libcurl et vérifiez que la version contient la mention "no_ssl" puis sélectionnez-la et cliquez de nouveau sur "Download Selected" et idem, laissez-vous guider.



Et voilà, c'est installé :-)

Microsoft Visual C++


Explication en anglais pour installer avec Visual C++

Petite exploration des fonctions de libcurl


Maintenant, regardons de plus près comment utiliser cette librairie pour télécharger une page web.
Certaines des fonctions utiles sont détaillées ici.
Nous aurons besoin des fonctions suivantes:
  • CURL *curl_easy_init( );
    Cette fonction est la première à appeler, elle initialise la session puis la stocke dans une variable de type CURL * qui est un type propre à la librairie, vous n'avez pas à vous en soucier.
  • CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
    Cette fonction est la plus délicate à utiliser. C'est ici que tout se passe en quelque sorte. Le premier argument est la session que vous avez initialisée. L'option et le parameter forment un couple de données qui forme un sens ensemble. C'est dans ce couple que vous configurez tout: l'url, la fonction à utiliser pour enregistrer le contenu téléchargé, le nom du fichier etc... Par exemple pour mettre l'url de la page à télécharger, option sera égal à CURLOPT_URL et parameter sera l'url du genre http://machin.com. On verra ça dans l'exemple. Mais il faut bien retenir que le type de parameter dépend fortement de l'option. On appele cette fonction autant de fois que l'on a des paramètres à passer.
  • CURLcode curl_easy_perform(CURL * handle );
    Ça, c'est la fonction magique, elle exécute le téléchargement.
  • void curl_easy_cleanup(CURL * handle );
    Ça, c'est une fonction qu'il vaut mieux ne pas oublier: elle libère les ressources utilisées durant la session que vous avez initialisée.


Allez on met en pratique!

Un exemple: télécharger la page d'accueil de CCM


On a besoin de télécharger la page d'accueil de CCM.
On enregistrera la page http://www.commentcamarche.net dans le fichier ./index_ccm.html
  • Fichiers d'en-tête, obligatoires pour utiliser les fonctions et types de la libcurl et aussi pour la gestion de notre fichier
    #include <curl/curl.h>
    #include <stdio.h>
  • Initialisation de la session
    CURL *session = curl_easy_init(); //Mouarf, trop facile
  • On précise l'url qui nous intéresse
    curl_easy_setopt(session, CURLOPT_URL, "http://www.commentcamarche.net");
  • On précise le nom de notre fichier destination qui recevra le contenu de la page
    FILE * fp = fopen("./index_ccm.html", "w"); //Création de notre fichier
    curl_easy_setopt(session,  CURLOPT_WRITEDATA, fp); //On balance notre pointeur de fichier comme destination 
  • On précise la fonction qui gèrera l'écriture dans notre fichier. Peut être n'êtes-vous pas habitués à cela, il faut mettre un pointeur de fonction en paramètre de curl_easy_setopt. Comme ça, curl_easy_setopt utilisera cette fonction pointée pour écrire dans le fichier. La fonction en question doit respecter la même en-tête que la fonction standard fwrite:
    size_t  fwrite(const  void  *ptr,  size_t  size,  size_t  nmemb,  FILE  *stream);
    Vous pouvez donc créer une fonction d'écriture de votre choix et la mettre en paramètre de curl_easy_setopt tant qu'elle possède la même en-tête que fwrite. Mais sincèrement si vous ne voulez pas vous prendre la tête, utilisez fwrite qui est déjà toute prête:
    curl_easy_setopt(session,  CURLOPT_WRITEFUNCTION, fwrite);
  • On a fait le plus dur si j'ose dire. Il ne reste plus qu'à lancer le téléchargement
    curl_easy_perform(session);
  • Enfin, on libère nos ressources utilisées
    fclose(fp);
    curl_easy_cleanup(session);

Notre fichier source


Voici donc ce que donne notre exemple:
#include <curl/curl.h>
#include <stdio.h>

int main(int argc, char **argv)
{
	CURL *session = curl_easy_init(); 
	curl_easy_setopt(session, CURLOPT_URL, "http://www.commentcamarche.net");
	FILE * fp = fopen("./index_ccm.html", "w"); 
	curl_easy_setopt(session,  CURLOPT_WRITEDATA, fp); 
	curl_easy_setopt(session,  CURLOPT_WRITEFUNCTION, fwrite);
	curl_easy_perform(session);
	fclose(fp);
	curl_easy_cleanup(session);
	return 0;
}

Compilation avec gcc (Unix/Linux)


Maintenant on va compiler ça. On appellera notre fichier ccm.c
Pour compiler, il sera important de préciser que l'on utilise la libcurl à l'éditeur de lien, pour qu'il sache où trouver les fonctions de libcurl. On rajoutera donc l'option -lcurl:
gcc ccm.c -o ccm -lcurl

Et voilà, il n'y a plus qu'à lancer notre application:
./ccm

Compilation sous Windows


Dev C++


Testé avec la version 4.9.9.2, comme tout à l'heure pour l'installation.

Créez un nouveau projet d'application en mode console.
Dans votre main.c, collez le code du fichier source de la section précédente. A présent, notre but sera d'indiquer au compilateur et à l'éditeur de lien, les options nécessaires pour la création de notre exécutable.
  • Compiler en mode statique. On va intégrer le code de la libcurl dans notre exécutable sans dépendre de la dll de libcurl. Ça s'appelle une compilation avec bibliothèque statique. C'est moins contraignant. Pour cela, on compilera en définissant la constante de macroprocesseur CURL_STATICLIB.
  • Dépendances de librairies statiques et dll. Oui il en faut bien des dll, comme certaines de Windows par exemple. Nous aurons besoin de la libcurl (évidemment), de la dll de gestion des sockets (Ws2_32.dll), de la zlib (librairie de compression des données) et de winmm.dll.


Pour définir tout cela, allez dans Outils / Options du compilateur puis ajoutez la commande suivante pour le compilateur:
-DCURL_STATICLIB

et les commandes suivantes pour l'éditeur de liens:
-lcurl -lWs2_32 -lz -lWinmm




Cliquez sur OK puis sur l'icône "Tout reconstruire", et à priori, le tour est joué :-)

Microsoft Visual C++


Explication en anglais pour compiler avec Visual C++ (même document que pour l'installation)

Notes


Cette librairie est certes un peu magique mais il y a des limites:
  • Vous ne téléchargerez que la page précisée, les fichiers dont dépend la page ne seront pas téléchargés (images, feuilles de style etc...). Si vous voulez tous les fichiers dont dépend une page, vous pouvez utiliser des programmes tout fait comme wget par exemple.
  • Vous n'aurez que le code source finalisé de la page, vous n'aurez pas le code source PHP d'une page web par exemple

Compléments


A voir également :

Ce document intitulé «  Télécharger le contenu d'une page WEB distante  » issu de CommentCaMarche (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.