IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Extraction de données sur un site internet

III Collecter les informations

L'application doit récupérer automatiquement le contenu de deux pages HTML pour chacun des films. Elle va dialoguer en HTTP avec le serveur cible. La meilleure façon d'établir ce dialogue est d'utiliser la commande shell cURL. cURL est un projet Open Source porté sous de nombreuses plates-formes, notamment Linux et Windows.
Cependant, pour les personnes qui ne peuvent pas installer cette commande sur leur serveur, nous verrons une solution alternative, en établissant un dialogue en sockets avec les fonctions réseau de Php. C'est une méthode moins élégante, la gestion du dialogue HTTP se fait "à la main".


1) cURL


  1-1) introduction
cURL est un outil puissant. cURL signifie "Client URL Request Library", ou encore "see URL". Si vous êtes administrateur réseau ou développeur internet, vous ne pourrez bientôt plus vous en passer. Il permet d'effectuer de nombreuses opérations en ligne de commande shell. Il peut par exemple récupérer le contenu d'une page internet, un fichier sur un ftp, utiliser le SSL, l'authentification Apache, un proxy, poster des données sur un formulaire http, etc.
Intégré dans un script, cURL permet également d'automatiser des tâches récurrentes de backup. Il sera l'allié indispensable de vos phases de test de sécurité sur vos pages internet.

1-2) installation
cURL se télécharge depuis son site : http://curl.haxx.se/
Il est possible de l'installer avec ou sans le support de SSL. Si vous disposez d'une distribution récente de Linux, cURL est probablement déjà présent sur la machine. Tapez curl dans une invite shell pour le vérifier.

  1-2.1) installation sous Windows
Je préconise le téléchargement du binary Win32. Il suffit ensuite de copier l'exécutable curl.exe dans un répertoire inclus dans le PATH.

1-2.2) installation sous Linux
Toute la procédure d'installation est expliquée en détail sur le site de cURL : http://curl.haxx.se/docs/install.html
En voici un bref résumé.

a-) Téléchargez les sources tar.gz, décompressez et compilez.
Pour les moins aguerris, voici la marche à suivre.

b-) décompression des sources :
  tar -zxvf curl-7.11.0.tar.gz

c-1) compilation. Cas n°1 : vous êtes root sur le serveur
  cd curl-7.11.0
installez curl avec les options par défaut.
  ./configure
  make
  make test
  make install
curl est installé dans /usr/bin/, donc accessible dans le PATH.

c-2) compilation. Cas n°2 : vous n'êtes pas root sur le serveur
  cd curl-7.11.0
installez curl dans votre home directory par exemple.
  ./configure --prefix=$HOME
  make
  make test
  make install

Note : ajouter --with-ssl à configure pour le support de SSL

Vous êtes fin prêt pour utiliser cURL.


1-3) exemples d'utilisation de cURL

- Téléchargement d'une page web
curl http://www.google.fr
le source de la page d'index de Google.fr s'écrit sur la sortie standard.

Pour l'enregistrer dans un fichier, redirigez la sortie :
curl http://www.google.fr > index.html

Des informations de progression se sont affichées sous le prompt :
  % Total    % Received % Xferd  Average Speed          Time             Curr.                                  Dload  Upload Total    Current  Left    Speed 100  3165  100  3165    0     0   5692      0  0:00:00  0:00:00  0:00:00 69771

Pour ne plus les afficher, rediriger la sortie programme (Linux seulement) :
curl http://www.google.fr 2> /dev/null > index.html

- Téléchargement d'un fichier en http
curl http://curl.haxx.se/download/curl-7.11.0.tar.gz > curl-7.11.0.tar.gz

- Téléchargement d'un fichier ftp sur un serveur en connexion anonyme
curl ftp://ftp.server.com/pub/fichier.tar.gz > fichier.tar.gz

- Téléchargement d'un fichier ftp sur un serveur avec authentification
curl -u user:password ftp://ftp.server.com/pub/fichier.tar.gz > fichier.tar.gz

- Téléchargement d'une page web avec un .htaccess
curl -u user:password http://www.server.com/private/page.php > page.html

- Téléchargement d'un fichier en http avec précision du referer
curl --referer http://www.server.com/index.php http://www.server.com/image/image01.jpg > image01.jpg
permet de satisfaire la règle de contrôle du referer de Apache qui empêche qu'une image soit référencée par un site concurrent.

- Téléchargement d'un fichier en http en passant par un proxy
curl --proxy proxyhost:port http://www.server.com/image/image01.jpg > image01.jpg
Utilise un proxy pour effectuer la connexion sur le serveur cible. Indispensable si vous devez passer par un Proxy pour sortir de votre réseau. Exemple Proxy+ (voir mon article "Démarrer avec Proxy Plus" : http://nepomiachty.developpez.com/proxyplus/)
Ou bien aussi pour des raisons moins avouables, car les logs du serveur cible ne retiendront que l'IP du proxy.

- Changer le nom du navigateur
Par défaut, lorsque cURL se connecte sur un serveur HTTP, il envoie comme valeur pour NavigatorName quelque chose comme :
"curl/7.9.8 (i386-redhat-linux-gnu) libcurl 7.9.8 (OpenSSL 0.9.7a) (ipv6 enabled)"
Si vous souhaitez changer cette valeur :
curl --user-agent "Mozilla/4.0 (compatible; MSIE 6.0;Windows NT 5.0)" http://www.server.com/image/image01.jpg > image01.jpg

Conclusion :
Toutes ces options peuvent être combinées, ce qui fait de cURL un outil extrêmement puissant.


1-4) implémentation de cURL dans notre code

Nous allons (enfin) commencer à taper un peu de code. Je suggère d'écrire une fonction qui prendra ses paramètres au moyen d'un tableau associatif. C'est une méthode qui laisse une grande liberté pour l'appel de la fonction.
Les paramètres retenus sont : l'url à appeler, le referrer, le proxy et le nom du navigateur. L'url à appeler est un paramètre obligatoire, les autres paramètres passeront par le tableau.

L'appel de la fonction se fera de la façon suivante :
   <?php
   $html = get_html(
      'http://www.server.com/page_lambda.php',
      array(
        'Referer'=>'http://www.server.com/index.php',
        'Proxy'=>'monproxy:8080',
        'BrowserName'=>'Mozilla/4.0 (compatible; MSIE 6.0;Windows NT 5.0)'
      )
   );
   ?>

L'utilisation d'un tableau associatif nous permet d'alléger l'appel si on a moins de paramètres :
   $html = get_html('http://www.server.com/page_lambda.php', array('Proxy'=>'monproxy:8080');
ou encore :
   $html = get_html('http://www.server.com/page_lambda.php');

Voici la fonction Php :

   function get_html($url, $parametres=array()) {
      $params='';
      if ($parametres['Referer']!="") $params.='-e '.$parametres['Referer'];
      if ($parametres['Proxy']!="") $params.='-x '.$parametres['Proxy'];
      if ($parametres['BrowserName']!="") $params.='-A "'.$parametres['BrowserName'].'"';
      return (`curl $params $url`);
   }

Notes :
a-) j'ai utilisé la notation courte de cURL :
 -e = --referer
 -x = --proxy
 -A = --user-agent
b-) l'appel se fait en laissant un shell (guillemets inversés)
ici, on suppose que cURL est dans le PATH, sinon, il faudra préciser son chemin d'accès.



2) Utilisation des sockets sous Php


  2-1) Comment se passe le dialogue entre le client et le serveur internet ?

Le dialogue HTTP se passe en connexion TCP sur le port 80. Les données échangées sont du texte. Ce dialogue est aisément reproductible grâce à la commande telnet. Exemple d'une connexion sur le site de Yahoo :
telnet www.yahoo.com 80
Puis sur la sortie standard, tapez les trois lignes suivantes :
<entrée> signifie que vous tapez sur la touche entrée du clavier.
GET / HTTP/1.1 <entrée>
Host: www.yahoo.com <entrée>
Connection: Close <entrée><entrée>


Le source de la page HTML s'affiche sur la sortie standard et telnet se ferme.
La première ligne signifie que la connexion se déroule suivant le protocole HTTP/1.1 La page demandée est la racine du site. Pour demander la page correspondant à l'url http://www.yahoo.com/news/europ_news.html (exemple fictif) la première ligne devient :
GET /news/europ_news.html HTTP/1.1 <entrée>


2-2) Implémentation sous Php

Il faut reproduire le même dialogue au moyen des fonctions réseau de Php. La fonction à écrire n'a pas besoin de prendre autant de paramètres que celle écrite précédemment pour la fonction cURL, car certaines options comme l'utilisation d'un proxy n'est pas possible. Par soucis de simplification, cette fonction ne prend en paramètre que l'url.

  <?php
  function get_html($url) {
    if (strtoupper(substr($url,0,7))=="HTTP://") $url=substr($url,7);
    $p = strpos($url,"/");
    if ($p===FALSE) {
      $nom_domaine=$url;
      $get="/";
    }
    else {
      $nom_domaine=substr($url,0,$p);
      $get=substr($url,$p);
    }
    
    $errno=""; $errstr=""; $r="";
    $fp = fsockopen($nom_domaine, 80, &$errno, &$errstr, 15);
    if($fp) {
      socket_set_timeout($fp, 15);
      fputs($fp,"GET $get HTTP/1.1\r\n");
      fputs($fp,"Host: $nom_domaine\r\n");
      fputs($fp,"Connection: Close\r\n\r\n");
      $r="";
      while(!feof($fp)) {
        $r.=fgets($fp,1024);
      }
      fclose($fp);
      return($r);
    }
    return('');
  }
  ?>


Explication :
Cette fonction prend en entrée une chaîne correspondant à l'url. Elle peut commencer par http://, ces caractères seront supprimés. Ensuite, elle sépare l'url en deux variables le nom de domaine ($nom_domaine) et la page sollicitée ($get).
La commande fsockopen initie le dialogue avec le serveur. socket_set_timeout règle le temps de réponse maximum du serveur à 15 secondes.
fputs écrit sur le flux ouvert. La réponse se lit immédiatement avec fgets (boucle while). Le dialogue est terminé lorsque le flux est vide, mais on le ferme proprement avec fclose.