Archives du 7 novembre 2008

Auteur : cyrilpop
• 7 novembre 2008 20:27
  • 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 ;)

    Auteur : cyrilpop
    • 7 novembre 2008 15:14

    Salut à tous, alors que je voulais faire une belle correction orthographique de mon précèdent billet je me suis aperçu que les élections nous suivaient vraiment partout… En effet, j’ai oublié un accent sur le mot connaître et que me propose Word pour corriger cela ? Je vous le donne en mille : ELECTION. Vous ne me croyez pas ? Et bien voici la preuve en images… Enjoy. Et c’est garanti sans montage photo…