Site Meter
Acceder:
Basado en Elgg

Rolando Espinoza La fuente :: Blog :: GeoIP: Resolviendo el país a partir de la dirección IP

agosto 12, 2008

Normalmente no hablo de lo que hago como programador... pero bueno, alguna vez tenía que empezar.

En este caso, implemente el feature de saber de qué país procede un usuario, el cual tiene muchas aplicaciones. Desde el simple "Tu país es xxx" hasta mostrar contenido personalizado de acuerdo al país del usuario.

MaxMind provee la base de datos de rangos de ip y el país al cual proceden en un formato CSV listo para cargar a la base de datos. La versión free/gpl tiene un 99.3% de precisión, no da ni ciudad ni coordenadas geográficas, pero nos sirva para empezar.

MaxMind da las instrucciones para utilizar los datos, http://www.maxmind.com/app/csv sugiere convertir manualmente la dirección IP a entero, pero mysql ya posee esa función.

Primero necesitamos la tabla:

 CREATE TABLE `geoip` (
  `beginip` varchar(16) NOT NULL,
  `endip` varchar(16) NOT NULL,
  `beginnum` int(11) unsigned NOT NULL,
  `endnum` int(11) unsigned NOT NULL,
  `code` varchar(2) NOT NULL,
  `country` varchar(128) NOT NULL,
  PRIMARY KEY  (`beginnum`),
  UNIQUE KEY `end_num` (`endnum`),
  KEY `code` (`code`)
) ENGINE=MyISAM;

La tabla contiene el mismo orden que las columnas del csv.

Luego cargamos el csv dentro mysql:

mysql> LOAD DATA LOCAL INFILE "geoip.csv" INTO TABLE `geoip`

FIELDS TERMINATED BY ',' ENCLOSED BY '"'

LINES TERMINATED BY '\n';

 

Con eso cargamos los más de 100000 registros.

Luego la consulta que nos retorna el país:

mysql> select code from geoip where endnum >= INET_ATON('166.114.108.10') order by endnum asc limit 1;
+------+
| code |
+------+
| BO   |
+------+
1 row in set (0.00 sec)

mysql> select code from geoip where endnum >= INET_ATON('169.23.46.2') order by endnum asc limit 1;
+------+
| code |
+------+
| US   |
+------+
1 row in set (0.04 sec)

mysql> select code from geoip where endnum >= INET_ATON('200.86.1.1') order by endnum asc limit 1;
+------+
| code |
+------+
| CL   |
+------+
1 row in set (0.06 sec)

 

Bueno, nosotros construimos nuestra aplicación encima de zend (framework), y en nuestro modelo GeoIp_Manager tenemos este método:

    public function findCountryByIp($ip) {
        if ($this->_ipvalidator->isValid($ip)) {
           $select = $this->select()
                ->where('endnum >= INET_ATON(?)', $ip);
           $iprange = $this->fetchRow($select, 'endnum asc');
           return $iprange->getCountry();
        }  else {
           throw new GeoIp_Exception("Invalid ip ($ip)");
        }
        // not found
        return null;
    }

Con eso obtenemos el país de un determinado ip, luego tenemos unos par de helpers para mostrar una banderita y demás chucherías. Algo similar a esto:

  $country = $geoip->findCountryByIp($request->getUserIp());

  echo $this->isoCountryFlag($country);

Pero tenemos los datos de los países en otra tabla, así quitamos los campos varchar de la tabla geoip y hacemos nuestra consulta más eficiente.

De a poco ire publicando más sobre el know-how que voy adquiriendo y me da sentimiento de culpabilidad no compartirlo, por que al final... yo tambien lo saque de algún lado Laughing

Palabras clave: findCountryByIp, geoip, pais, zend

Enviado por Rolando Espinoza La fuente


Comentarios

  1. Hey!, en Ajayu se hablo de publicar el IP de los comentaristas anónimos ¿recuerdas?. En su lugar podría crearse un plugin para ELGG que nos indique la nacionalidad de los participantes (sabes que tenemos amigos por todo lado) incluyendo los anónimos. Este si sería un uso racional ¿no lo crees?.

    jmt4b04d4vjmt4b04d4v on jueves, 14 agosto 2008, 23:23 UTC # |

  2. Muy bueno que hayas compartido esto, la verdad que l mejor de todo es poder conseguir la lista de IPs por Pais.

    Gracias

    Boris BarrosoBoris Barroso on viernes, 15 agosto 2008, 23:35 UTC # |

  3. Nice realmente muy util, y la version pago aumenta la precision? y ellos de donde sacan esa informacion?

    Marcelo Zambrana VillarroelMarcelo Zambrana Villarroel on jueves, 21 agosto 2008, 05:41 UTC # |

  4. Yo creo que saber qué ips estan asignadas a una región es fácil, ¿sólo habría que preguntar al icann?

    Para ser más preciso, se podría intentar preguntar a Entel que IPs utiliza para cada departamento o ciudad, así vamos contruyendo nuestra db más precisa :D

    Rolando Espinoza La fuenteRolando Espinoza La fuente on jueves, 21 agosto 2008, 12:42 UTC # |

  5. umm tu crees que Entel va a soltar esa info asi por asi? si unos paranoicos esos

    Marcelo Zambrana VillarroelMarcelo Zambrana Villarroel on viernes, 22 agosto 2008, 04:22 UTC # |

  6. @see eMulePlus.

    jmt4b04d4vjmt4b04d4v on domingo, 24 agosto 2008, 19:37 UTC # |

Debes iniciar sesión para enviar un comentario.