Geolocalizar números de IP



Hace un par de años, cuando intenté retomar mi carrera, en un TP (si, me tocó hacer un TP) quise aprovechar el tráfico de este site para armar el proyecto, básicamente había que hacer un sistema que tomase datos reales (las stats de un sitio son un lindo ejemplo de ello) y realizase varas operaciones. Eso servía como dato, pero lo que quería hacer en el proyecto involucraba detectar de qué país era cada número de IP de ustedes.

Lindo problema, nunca me había encontrado con la necesidad, pero hoy por hoy es algo más que necesario, desde campañas de publicidad hasta estadísticas más o menos fieles, la geolocalización te permite mostrar contenido preferencial para algún país, ocultarlo para otro o simplemente avisarle al usuario que hay algo especial si viene de X destino, algo que tan sólo con el número de IP no se puede obtener, hace falta algo más.

Ese algo más es lo que les explicaré en este post con la solución que hay dando vueltas y cómo implementarla en cualquier proyecto.



Primero que nada, un número de IP es tan sólo eso, no dice a qué país fue asignado, segundo, un número puede pertenecer a un país durante un tiempo, luego ser vendido a otro, en todo caso hace falta una tabla de conversión más o menos fiable.

La gente de Maxmind tiene una versión "lite" para los pobres que no necesitamos más y luego te venden paquetes mucho más completos que incluyen hasta las ciudades, regiones, proveedores, velocidades, etc. Por lo pronto lo único que necesitaba yo era saber el país, así que pude optar por la versión gratuita.

La base de datos GeoIP que ofrece Maxmind en su versión lite se puede descargar de dos formas, un archivo binario .dat accesible con sus APIs o una linda lista CSV que se puede meter desde en un excel hasta un SQL de cualquier tipo, eso a gusto del usuario.

Ahora bien, según ellos el .dat es más eficiente, ofrecen código para muchos lenguajes, también benchmarks por si no les creemos, fáciles de testar, el tema es que en SQL es una búsqueda entre números, en el .dat puede utilizar otros algoritmos de búsqueda más cómodos para este tipo de resultado.

La tabla en particular hace una conversión decimal de los números de IP, para aquellos que quieran trabajar sin usar el código de MaxMind pueden hacerlo uds mismos, no es tan difícil.

Un ejemplo en PHP para obtener el valor decimal de un número de IP (IPV4) $parts = explode(".", $ip);
$numeric_ip = $parts[3] + (256 * $parts[2]) + (256 * 256 * $parts[1]) + (256 * 256 * 256 * $parts[0]);


Como verán es bastante boludo, tan sólo un explode para separalo en sus cuatro partes, luego se hacen múltiplos y se suma todo, esto nos dará un número entero y la búsqueda se hace entre esos números.

En MySQL ya existe una forma de hacerlo:

SELECT ip_country
FROM geoip
WHERE
INET_ATON("174.36.207.186") BETWEEN begin_ip_num AND end_ip_num
LIMIT 1


Gracias a la funcoón INET_ATON que hace exactamente lo mísmo, sólo pasamos el número de IP y listo, obtenemos el decimal

La tabla tiene rangos y código de país y nombre, entonces la búsqueda es bastante fácil, hay que obtener "entre qué y qué" estás y ya obtendrás el dato de país. Obviamente depende del uso que le des la performance que pueda tener esto.

Por ejemplo, yo lo implementé en este blog, sólo para usuarios registrados, en el área de usuarios online, allí podrán ver la banderita de cada país por cada usuario con sesión activa, se muestran los que estuvieron en el sitio en los últimos 250 segundos creo.

Para hacerlo creé una función sencilla que llame al código PHP que ellos ofrecen, preferí saltear la opción MySQL y consultar directo en el .dat, la razón de esto es performance, pero de paso para probar si realmente era mejor:

include("geoip/geoip.inc");

function consultaGeoIP($ip)
{
$gi = geoip_open("/home/fabioco/public_html/plugins/geoip/GeoIP.dat",GEOIP_STANDARD);
$pais = geoip_country_code_by_addr($gi, $ip);
geoip_close($gi);

return $pais;
}


Podemos obtener también el nombre del país pero yo quería el código de dos letras, luego me busqué unas banderitas que respetasen el código, encontré un buen set completísimo en GoSquared que tiene banderas de tamaños diversos, 16×16, 24×24, 32×32, 48×48, y 64×64. Me quedé solamente con las de 16 pixeles, más no hacía falta, son como 241 archivos PNG con un total de 57.369 bytes , digamos que no es muy pesado y seguramente uno no recibe tanta variedad de visitas, no creo que nadie de Burkina Faso visite el blog (chequeo Analytics: en los últimos 3 años recibí 10 visitas de Burkina Faso, me cagó el Analytics)

Tan sólo llamando a código de país + .png ya tenemos la imagen de la bandera del país visitante, obviamente hay casos en los que no tendremos país alguno, todo puede fallar, pueden ponerle una bandera pirata si quieren para esos casos :D

Y así quedó:



Ahora bien ¿Para qué me sirve? en mi caso sucede a veces que tengo campañas que son exclusivas para ciertos países, uno podría vender todo el stock de impresiones si es que fuese un banner, pero ¿que pasa si uno tiene un concurso o un post en particular? podría segmentarlo por país fácilmente con este recurso, no es que sea lo idealm pero sirve.

Por otra parte, supongamos que uno es un disidente rabioso de su país que lo persigue, nadie se enteraría de mucho si filtrase a su propio país, claro, es el disidente más inútil de todos los tiempos, algo así como una Yoani Sanchez :D

Pero en términos prácticos sirve mucho para ofrecer distinto contenido para distintos públicos, un ejemplo sería un sitio de noticias que podría "priorizar" notas locales a cada visitante sólo por la zona desde donde viene.

Yo no soy muy partidario de "negar" información a alguien que viene de una locación en particular, me parece detestable encima que no exista forma de tener una vista por default y que uno, en tal caso, tenga la opción. Muchos cometen este error con el tema del idioma ¿Quien cuernos te dijo que yo quiero ver la versión española de tu sitio que es un 10% de la versió en inglés? varios sitios famosos cometen este "crimen" de la web.

Es subestimar bastante al usuario, pero sí se puede organizar diferente el contenido, que tenga prioridad el contenido local sin eliminar el internacional, es una buena opción.

Después, como en el caso de las banderitas, es tan sólo un capricho :D lo hice porque podía hacerlo :P

Otros posts que podrían llegar a gustarte...

Comentarios

  • Hackkpo    

    Muy interesante, pero hay algo que no entendi, por un lado decis que:

    "Primero que nada, un número de IP es tan sólo eso, no dice a qué país fue asignado, segundo, un número puede pertenecer a un país durante un tiempo, luego ser vendido a otro, en todo caso hace falta una tabla de conversión más o menos fiable. "

    Y por otro la gente de MaxMind dice tener la tabla de relacion IPv4 (decimal)/Pais al que pertenece.. ¿Porque es 100% esa tabla?

    • Responder
    • Citar
    • Comentado:
  • Hackkpo    

    100% confiable, me comi la palabra confiable, perdon :P

    • Responder
    • Citar
    • Comentado:
  • quiero mi banderita en los comments! :D

    Edit. solo vi dos usuario online registrados, y uno sos vos! /FOREVER-ALONE

    • Responder
    • Citar
    • Comentado:
    • Revisado: 04/05/2013 - 18:59:28
  • Hackkpo dijo:

    Muy interesante, pero hay algo que no entendi, por un lado decis que:

    "Primero que nada, un número de IP es tan sólo eso, no dice a qué país fue asignado, segundo, un número puede pertenecer a un país durante un tiempo, luego ser vendido a otro, en todo caso hace falta una tabla de conversión más o menos fiable. "

    Y por otro la gente de MaxMind dice tener la tabla de relacion IPv4 (decimal)/Pais al que pertenece.. ¿Porque es 100% esa tabla?


    el tema es este, sí o sí necesitás una tabla de conversión porque la relación IP-país no es constante.

    entonces tenés que estar actualizando cada cierto tiempo la base que generan los de MaxMind, ellos estan todo el tiempo laburando eso (es su negocio, por eso te venden las bases de datos más complejas)

    si quisieras mantener vos una tabla semejante actualizada deberías vivir haciendo un whois de tooodos los rangos de ip del mundo, un laburo al pedo que mejor que lo haga otro.

    también podrías hacer un whois por cada visitante que tenés, pero ahí el costo es mucho mayor, esta es la solución eficiente, claro

    • Responder
    • Citar
    • Comentado:
  • luis barrios dijo:

    quiero mi banderita en los comments! :D


    ¿para? antes mejor sería poner un sistema de puntuación de comentarios que también estuve pensando...

    • Responder
    • Citar
    • Comentado:
  • Fabio Baccaglioni dijo:

    luis barrios dijo:
    quiero mi banderita en los comments! :D


    ¿para? antes mejor sería poner un sistema de puntuación de comentarios que también estuve pensando...


    para que? solo porque podes hacerlo! :D
    es buena lo de la puntuacion, pero solo para usuarios registrados. sino cualquier troll vota negativo a cualquier cosa

    • Responder
    • Citar
    • Comentado:
  • luis barrios dijo:

    Fabio Baccaglioni dijo:
    luis barrios dijo:
    quiero mi banderita en los comments! :D


    ¿para? antes mejor sería poner un sistema de puntuación de comentarios que también estuve pensando...


    para que? solo porque podes hacerlo! :D
    es buena lo de la puntuacion, pero solo para usuarios registrados. sino cualquier troll vota negativo a cualquier cosa


    eso desde ya, privilegio de usuario registrado, así los trolls tienen su merecido a merced de uds :D

    • Responder
    • Citar
    • Comentado:
  • eduqlm    

    ¿Cuando vas a unificar los usuarios para todos los sitios? (Fabio, LDV, TG, Opinology). Guiño
    Todavía me debes los stats de (# comments / # views)

    • Responder
    • Citar
    • Comentado:
  • eduqlm dijo:

    ¿Cuando vas a unificar los usuarios para todos los sitios? (Fabio, LDV, TG, Opinology). Guiño
    Todavía me debes los stats de (# comments / # views)


    jamás, no me interesa en lo más mínimo, son sitios totalmente separados que quiero que tengan vida propia, TG ni siquiera tiene usuarios, LDV debe vivir por su propia cuenta, y mi blog seguirá siendo siempre mío así que no me ineteresa y no lo creo conveniente.

    con respecto a las stats, cuando tenga ganas y tiempo de ponerme con el SQL del blog para ver eso :P

    • Responder
    • Citar
    • Comentado:
  • Gracias por el artículo: me hiciste acordar del tema y me puse a revisar hace cuánto no actualizaba la lista de IPs (manejo todo en mi servidor, porque chequeo todas las visitas para presentar precios/publicidad según el país a cada uno de los usuarios, registrados o no).

    Resultó que desde el 2008 no corría la actualización.

    Ahora estoy poniéndome al día.

    • Responder
    • Citar
    • Comentado:
  • Walter    

    en ubuntu o derivados se puede hacer:
    $ apt-get install php5-geoip
    y con esto ya se tendria todo lo necesario para usar las funciones de geoip http://www.php.net/manual/en/ref.geoip.php

    • Responder
    • Citar
    • Comentado:
  • Walter dijo:

    en ubuntu o derivados se puede hacer:
    $ apt-get install php5-geoip
    y con esto ya se tendria todo lo necesario para usar las funciones de geoip http://www.php.net/manual/en/ref.geoip.php


    si, es una buena opción pero en la mayoría de los hostings no incluyen la extensión así que estás dependiendo de que el sysadmin tenga buena onda, si encima tu site está en un host de esos grandes, olvidate, nunca lo instalarán

    lo bueno de la versión nativa es la performance, claro.


    Diego Ruiz dijo:
    Gracias por el artículo: me hiciste acordar del tema y me puse a revisar hace cuánto no actualizaba la lista de IPs (manejo todo en mi servidor, porque chequeo todas las visitas para presentar precios/publicidad según el país a cada uno de los usuarios, registrados o no).

    Resultó que desde el 2008 no corría la actualización.

    Ahora estoy poniéndome al día.


    jajaja en números de IP eso si que estaba desactualizado :P

    • Responder
    • Citar
    • Comentado:
  • diegote    

    Me voy a hacer full user si hago buenos comments?
    Taring* (?)

    • Responder
    • Citar
    • Comentado:
  • justino    

    el viernes después de pagar 5 CUC (un poco mas de 5 USD) pude tener acceso a internet en CUBA, y entre otras cosas q hice en esa meda hora fue entrar a FABIO.COM.AR, menos mal q no me geo bloqueaste!

    • Responder
    • Citar
    • Comentado:
  • justino dijo:

    el viernes después de pagar 5 CUC (un poco mas de 5 USD) pude tener acceso a internet en CUBA, y entre otras cosas q hice en esa meda hora fue entrar a FABIO.COM.AR, menos mal q no me geo bloqueaste!


    pero nene, cómo voy a bloquear a los hermanos cubanos que apenas navegan!

    • Responder
    • Citar
    • Comentado:
  • Vos escribis:


    Tan sólo llamando a código de país + .png ya tenemos la imagen de la bandera del país visitante, obviamente hay casos en los que no tendremos país alguno, todo puede fallar, pueden ponerle una bandera pirata si quieren para esos casos :D

    el codigo de pais que te devuelve son 2 letras (AR, BR, FR) y los pngs son los nombres...

    No entiendo lo de "Codigo de pais + .png"...

    Saludos.

    • Responder
    • Citar
    • Comentado:
  • Axel Wdoviak dijo:

    Vos escribis:


    Tan sólo llamando a código de país + .png ya tenemos la imagen de la bandera del país visitante, obviamente hay casos en los que no tendremos país alguno, todo puede fallar, pueden ponerle una bandera pirata si quieren para esos casos :D

    el codigo de pais que te devuelve son 2 letras (AR, BR, FR) y los pngs son los nombres...

    No entiendo lo de "Codigo de pais + .png"...

    Saludos.


    los PNG que yo bajé tienen de nombre dos letras (el código) y la extensión, fijate bien cual bajaste!

    • Responder
    • Citar
    • Comentado:

Deje su comentario:

Tranquilo, su email nunca será revelado.
La gente de bien tiene URL, no se olvide del http/https
Para evitar bots, si se tardó mucho en leer la nota seguramente no sirva y tenga que intentar dos veces

Negrita Cursiva Imagen Enlace


comentarios ofensivos o que no hagan al enriquecimiento del post serán borrados/editados por el administrador