Auteur : cyrilpop
• 7 novembre 2008
  • Présentation

Salut à tous, on m’a demandé plusieurs fois comment j’ai réussi « l’exploit » de trouver la ville d’une personne qui visite votre site internet. Ça se passe en plusieurs étapes.

Déjà un pré-requis est d’avoir un serveur dédié pour optimiser les choses…

Il y a un site très intéressant qui regroupe toutes les IP et à quelle ville cela correspond. Donc une fois la correspondance trouvée il suffit de récupérer l’IP du visiteur et le tour est joué… Enfin presque.

  • Préparation de la base de données

Dans un premier temps il faut récupérer le fichier et l’entrer dans sa base de données. Créer les tables avec la requête suivante :

  1. – Structure de la table `City_Block`
  2.  
  3. CREATE TABLE `City_Block` (
  4. `startIpNum` bigint(10) NOT NULL,
  5. `endIpNum` bigint(10) NOT NULL,
  6. `locId` bigint(10) NOT NULL
  7. ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
  8. – ——————————————————–
  9.  
  10. – Structure de la table `City_Location`
  11.  
  12. CREATE TABLE `City_Location` (
  13. `locId` bigint(10) NOT NULL,
  14. `country` varchar(2) NOT NULL,
  15. `region` varchar(2) NOT NULL,
  16. `city` varchar(50) NOT NULL,
  17. `postalCode` varchar(5) NOT NULL,
  18. `latitude` varchar(7) NOT NULL,
  19. `longitude` varchar(7) NOT NULL,
  20. `metroCode` varchar(5) NOT NULL,
  21. `areaCode` varchar(5) NOT NULL,
  22. PRIMARY KEY (`locId`)
  23. ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
  • Remplissage de la base de données
  • Pour intégrer le fichier dans sa base de données écrire le script suivant.

    1. LOG=/log/geoip.log
    2. echo "" >>; $LOG
    3. echo "Debut du remplissage `date`">>$LOG
    4. DATE=`date +%Y%m`
    5. adresse=http://www.maxmind.com/download/geoip/database/GeoLiteCity_CSV/
    6. cd /tmp
    7. wget http://www.maxmind.com/download/geoip/database/GeoLiteCity_CSV/
    8. fic=`cat index.html | grep zip | cut -d\" -f6 | tail -1`
    9. rm index.html
    10. wget $adresse/$fic
    11. unzip $fic
    12. rm $fic
    13. cd GeoLiteCity*
    14. pwd
    15. sed -e s/\"//g GeoLiteCity-Blocks.csv > GeoLiteCity-Blocks.tmp && mv -f GeoLiteCity-Blocks.tmp GeoLiteCity-Blocks.csv
    16. sed -e s/\"//g GeoLiteCity-Location.csv > GeoLiteCity-Location.tmp &&  mv -f GeoLiteCity-Location.tmp GeoLiteCity-Location.csv
    17. mysql -uUSER -pPASSWD < < EOF
    18. use geoip
    19. TRUNCATE TABLE City_Block;
    20. TRUNCATE TABLE City_Location;
    21. LOAD DATA LOCAL INFILE ‘GeoLiteCity-Blocks.csv’
    22. INTO TABLE City_Block
    23. FIELDS TERMINATED BY ‘,’
    24. LINES TERMINATED BY ‘\n‘;
    25.  
    26. LOAD DATA LOCAL INFILE ‘GeoLiteCity-Location.csv’
    27. INTO TABLE City_Location
    28. FIELDS TERMINATED BY ‘,’
    29. LINES TERMINATED BY ‘\n‘;
    30. exit
    31. EOF
    32. echo "—–Nombres d‘entrees pour les blocks : `wc -l GeoLiteCity-Blocks.csv`">>$LOG
    33. echo "Fin du remplissage `date`">>$LOG
    34. echo "–nb d entrees pour les vilels : `wc -l GeoLiteCity-Location.csv`">> $LOG
    35. cd /tmp
    36. rm -rf GeoLiteCity*
    37. echo "Fin du traitement `date`"

    Le fichier est mis à jour une fois par mois. Vous pouvez donc intégrer le script dans votre crontab. Personnellement j’ai essayé de le faire le 2 du mois mais il y a eu comme un bug, du coup je le fais le 5 du mois et ca marche très bien :)

    • Intégration dans une page internet

    C’est bien joli d’avoir une belle base de données, mais encore faut-il pouvoir l’utiliser. Le principe de fonctionnement de la base est qu’une ip qui s’ecrit normalement en 10.2.5.9 s’écrit en un seul chiffre. Comment est-ce possible ? Tout simplement en utilisant une base 256… Et oui de 0 à 255 ca fait bien 256 chiffres; Je vous passe la conversion mais c’est le même principe que les conversions hexa, binaire… Ensuite comme les donnes fonctionne par plage il suffit de trouver à quelle plage appartient notre IP et le tour est joué.
    Voici donc le code qu’il faut inclure dans votre page web :

    1. < ?php
    2. //*********************************************************
    3. // Retourne l’adresse IP du visiteur
    4. //*********************************************************
    5. function get_Ip() {
    6.         if(isset($_SERVER[‘HTTP_X_FORWARDED_FOR’])) {
    7.                 $ip = $_SERVER[‘HTTP_X_FORWARDED_FOR’];
    8.         }
    9.         elseif(isset($_SERVER[‘HTTP_CLIENT_IP’])) {
    10.                 $ip  = $_SERVER[‘HTTP_CLIENT_IP’];
    11.         }
    12.         else {
    13.                 $ip = $_SERVER[‘REMOTE_ADDR’];
    14.         }
    15.         return $ip;
    16.  }
    17.  
    18.  
    19.  //*********************************************************
    20.  // fonction qui ransforme l’IP en nombre
    21.  //*********************************************************
    22.  function IPAddress2IPNumber($dotted)
    23. {
    24.         $dotted = preg_split( "/[.]+/", $dotted);
    25.         $ip = (double) ($dotted[0]*16777216)+($dotted[1]*65536)+($dotted[2]*256)+($dotted[3]);
    26.         return $ip;
    27.  }
    28.  
    29. //***************************************
    30. //Fonction pour avoir la ville
    31. //**************************************
    32. function IpEnVille($uneIp)
    33.  {
    34.  
    35.                 $db = mysql_connect(‘localhost’, ‘root’, ‘mot_de_passe’);
    36.                 mysql_select_db(‘brikole’,$db);
    37.  
    38.                 // transforme l’ip en nombre
    39.                 $uneIp=IPAddress2IPNumber($uneIp);
    40.  
    41.                 $sql_locId ="SELECT City_Block.locId  FROM City_Block WHERE ‘".$uneIp."’ BETWEEN startIpNum AND endIpNum ";
    42.                 $req = mysql_query($sql_locId);
    43.                 $data = mysql_fetch_assoc($req);
    44.                 $retour=$data[locId];
    45.                 $locId=$retour;
    46.  
    47.                 $sql_city = "SELECT City_Location.city FROM City_Location WHERE locId     = ‘".$locId         ."’;";
    48.                 $req = mysql_query($sql_city);
    49.                 $data_city = mysql_fetch_assoc($req);
    50.                 $city=$data_city[city];
    51.                 mysql_close();
    52.  
    53.                 return $city;
    54. }

    Ensuite il suffit d’appeler la fonction de cette facon

    1. IpEnVille(Get_Ip());

    Voilà, si vous avez des questions n'hésitez pas... Mais en suivant step by step ca devrait aller tout seul ;)

    Vous pouvez suivre toutes les réponses à à ce billet via le flux RSS 2.0. Vous pouvez laisser une réponse, ou un rétrolien depuis votre propre site.

    14 réponses

    1. 1
      Fugitif 

      Ton blog à convertis les && en &
      Sinon le remplissage fonctionne
      Debut du remplissage samedi 8 novembre 2008, 10:03:08 (UTC+0100)
      —–nb d entrees pour les blocks : 3014820 GeoLiteCity-Blocks.csv
      Fin du remplissage samedi 8 novembre 2008, 10:05:29 (UTC+0100)

    2. 2
      Fugitif 

      Mince, il les convertis dans les commentaire. Je parlait des & a m p ;

    3. 3
      cyrilpop 

      Voilà j’ai corrigé ce petit bug ;) merci de l’info, j’avais pas fait attention ^^

    4. 4
      Fugitif 

      Sinon ca marche impec. Je l’ai un peu modifier a ma sauce.
      Merci encore

    5. 5
      valtientert 

      Спасибо за пост! Добавил блог в RSS-ридер, теперь читать буду регулярно..

    6. 6
      Fugitif 

      Tu a une faute à « Préserntation »

    7. 7
      Fugitif 

      Ah j’oubliait. Penser a supprimer les 2 premières lignes des fichiers GeoLiteCity-Blocks.csv et GeoLiteCity-Location.csv

    8. 8
      RYErnest 

      Nice post u have here :D Added to my RSS reader

    9. Благодарствую, полезная вещь.

    10. 10
      général03 

      Le script donné qui permet de remplir la base de données est un script PHP?

    11. 11
      Guillaume 

      Bonjour Cyril, merci pour ce script qui a l’air fort intéressant !
      Mais je ne vois pas ce qu’on doit faire du script pour remplir la base de données.
      Ce n’est pas du php mais une commande unix c’est ça ?
      Où doit on la copier ?
      Dans un fichier sur le serveur puis donner l’adresse à CronJobs ?

      Ou copier directement les commandes dans CronJobs ?

      Dans les deux cas j’ai des erreurs de la part de CronJobs, j’imagine que ce n’est pas comme ça qu’on procède, si ?

    12. Качественные генераторы – G1, FG, TCC, SDMO, Gesan

    1. 13
      Cyrilpop dans tous ses états (via un notification par ping)

      [...] modifié le billet permettant de récupérer la ville d’un visiteur d’un site web car le fichier à télécharger n’a plus le même nom… Donc mettez à [...]

    2. 14
      CREER UN SITE WEB 2.0 (via un rétrolien)

      CREER UN SITE WEB 2.0…

      LOGICIEL DE GESTION CMS POUR CREER ET GERER DES SITES WEB EN LIGNE…

    Laisser un commentaire