Ofrecer contenido personalizado al usuario basado en su ubicación

Escrito por el , actualizado el .
planeta-codigo programacion software software-libre
Enlace permanente Comentarios

Cuando navegamos por internet el navegador envía mútiple información sobre nosotros y algunas páginas web recopilan esa información y la procesan para ofrecer contenido personalizado que creen nos resultaría de interés. Contenido con mayor relevancia para el usuario mejora la experiencia de usuario y la páginas web mejorarán su ratio de conversión y facturación. La información que proporcionamos sin ser conscientes son las cookies, la dirección IP, el navegador que usamos, el sistema operativo, nuestra resolución de pantalla, la hora a la que accedemos a la página, … en base a ella y aunque la información está impersonalizada sirve para identificarnos como inequivocamente usuarios. Con la dirección IP y usando una base de datos es posible obtener al menos el país desde el que se accede a una web y muy posiblemente la ciudad.

Linux

GNU

Java

Un usuario cuando navega por internet proporciona diversa información que las páginas web pueden utilizar para personalizar el contenido que le muestran. La información que el usuario proporciona es el navegador que utiliza, sistema operativo y dirección IP. Con las cookies las páginas web pueden almacenar información en su navegador que persista en varias sesiones. Amazon por ejemplo personaliza el contenido que ve el usuario cuando accede a la página de inicio mostrando diferentes categorías de productos en los que puede estar más interesado, por ejemplo, productos visitados en anteriores sesiones, relacionados o similares. Si el usuario ha visitado un producto con anterioridad es muy posible que esté interesado en comprar ese producto con lo que Amazon se lo muestra de nuevo en la siguiente sesión o le envía un correo electrónico al día siguiente como recordatorio. Una página de eventos, viajes, hoteles, restaurantes, museos, el tiempo, … puede mostrar información basada en la localización, por ejemplo, si alguien está en Madrid quizá esté interesando dependiendo de la búsqueda que haga en eventos, hoteles o museos en esa ciudad.

En Arch Linux al igual que en muchas otras distribuciones GNU/Linux hay unos comandos y unos paquetes que contienen una base de datos que en base a la dirección IP proporciona el país, ciudad, código postal y coordenadas geográficas de latitud y longitud, son geoip con información del país y geoip-database-extra para obtener información de la ciudad. La localización de un usuario también puede obtenerse usando una consulta que implique red de datos hacia algún servicio y si el usuario en su navegador lo permite proporcionar la información de su geoposicionamiento, la diferencia es que la petición que haga uso de red añade algo de latencia a la respuesta de la aplicación tampoco requieren pedir permisos al usuario para activar su geoposicionamiento. La información proporcionada por geoip quizá no sea tan exacta en todos los casos que los anteriores métodos pero más que suficiente en la mayoría. En caso de querer la mejor precisión se puede optar primeramente pedir al usuario que comparta su localizacion mediante el navegador, luego o en la primera petición hasta que el usuario comparta su posición por usar la base de datos de geoip, si esta no es exacta aunque seguramente proporcione al menos el país pero no proporciona la ciudad se puede optar por usar algún servicio que implique red.

Instalados los paquetes con las bases de datos de geoposicionamiento en la distribución GNU/Linux su uso desde la línea de comandos es el siguiente, indicando la dirección IP o nombre de dominio de la que queramos conocer su ubicación:

1
2
3
4
$ geoiplookup 85.84.77.93
GeoIP Country Edition: ES, Spain
GeoIP City Edition, Rev 1: ES, N/A, N/A, N/A, N/A, 40.400002, -3.683300, 0, 0
GeoIP ASNum Edition: AS12338 Euskaltel S.A.
geoiplookup-85.84.77.93.sh
1
2
3
4
$ geoiplookup 8.8.8.8
GeoIP Country Edition: US, United States
GeoIP City Edition, Rev 1: US, CA, California, Mountain View, 94040, 37.384499, -122.088097, 807, 650
GeoIP ASNum Edition: AS15169 Google Inc.
geoiplookup-8.8.8.8.sh
1
2
3
4
$ geoiplookup marca.es
GeoIP Country Edition: ES, Spain
GeoIP City Edition, Rev 1: ES, 29, Madrid, Madrid, 28001, 40.416500, -3.702600, 0, 0
GeoIP ASNum Edition: AS9052 Unidad Editorial S.A.
geoiplookup-marca.es.sh

Comando para obtener información de geoposicionamiento en base a la dirección IP

Comando para obtener información de geoposicionamiento en base a la dirección IP

Otra opción es usar otra base de datos de geolocalización para direcciones IP, en vez de instalar un paquete en el sistema y usar el comando geoiplookup y procesar su salida con las bases de datos de MaxMind GeoLite2 para paises y ciudades dispondremos de una API accessible desde el lenguaje de programación que prefiramos. En este ejemplo usaré Java pero hay bindings para los lenguajes más populares.

Este sería el código para obtener la información de forma más sencilla que lanzar un proceso del sistema y parsear su resultado, además con GeoLite2 la aplicación no necesitará que el sistema tenga un paquete instalado y será más autocontenida. La base de datos de geolocalización se proporciona en un archivo que es posible distribuir con la aplicación.

En el siguiente ejemplo no incluyo la base de datos en el código fuente del proyecto ya que ocupa casi 65MiB. Descargada, descomprimida y ubicada en el directorio src/main/resources la aplicación se iniciar con el comando ./gradlew run.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package io.github.picodotdev.blogbitix.javageolocation;

import java.io.InputStream;
import java.net.InetAddress;

import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.record.City;
import com.maxmind.geoip2.record.Country;
import com.maxmind.geoip2.record.Location;
import com.maxmind.geoip2.record.Postal;
import com.maxmind.geoip2.record.Subdivision;

public class Main {

    public static void main(String[] args) throws Exception {
        // Acceder a la base de datos
        InputStream database = Main.class.getResourceAsStream("/GeoLite2-City.mmdb");
        DatabaseReader reader = new DatabaseReader.Builder(database).build();

        InetAddress ip = InetAddress.getByName("85.84.77.93");

        // Hacer la búsqueda
        CityResponse response = reader.city(ip);

        // País
        Country country = response.getCountry();
        System.out.printf("ISO Code: %s%n", country.getIsoCode());
        System.out.printf("Country: %s%n", country.getName());
        System.out.printf("Country (zh-CN): %s%n", country.getNames().get("zh-CN"));

        Subdivision subdivision = response.getMostSpecificSubdivision();
        System.out.printf("Subdivision Name: %s%n", subdivision.getName());
        System.out.printf("Subdivision ISO Code: %s%n", subdivision.getIsoCode());

        // Ciudad
        City city = response.getCity();
        System.out.printf("City: %s%n", city.getName());

        // Código postal
        Postal postal = response.getPostal();
        System.out.printf("Postal Code: %s%n", postal.getCode());

        // Geolocalizacion
        Location location = response.getLocation();
        System.out.printf("Latitude: %s%n", location.getLatitude());
        System.out.printf("Longitude: %s%n", location.getLongitude());
    }
}
Main.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
description = 'JavaGeolocation'
version = '0.1'

apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'java'
apply plugin: 'application'

mainClassName = 'io.github.picodotdev.blogbitix.javageolocation.Main'

repositories {
    mavenCentral()
}

dependencies {
    compile 'com.maxmind.geoip2:geoip2:2.7.0'

    compile 'org.slf4j:slf4j-api:1.7.21'
    runtime 'org.apache.logging.log4j:log4j-api:2.5'
    compile 'org.apache.logging.log4j:log4j-slf4j-impl:2.5'
    runtime 'org.apache.logging.log4j:log4j-core:2.5'
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.13'
}
build.gradle

Información de geoposicionamiento en base a la dirección IP con GeoLite2

Información de geoposicionamiento en base a la dirección IP con GeoLite2

GeoLite2 tiene una licencia Creative Commons Attribution-ShareAlike y no tiene coste, MaxMind proporciona además otras bases de datos más completas pero con un coste, 50$ para la base de datos de paises más 24$ para las actualizaciones y 370$ para la base de datos de ciudades más 100$ para las actualizaciones.

En una aplicación web Java en la interfaz ServletResquest y con el método getRemoteAddr() obtenemos la dirección IP del usuario, ya solo nos queda lanzar un proceso del sistema desde Java que invoque al comando geoiplookup con la dirección IP obtenida o usar la API Java u de otro lenguaje de MaxMind GeoLite2, obtener la salida del proceso, interpretarla y hacer con ella lo que queramos hacer en la aplicación. En una aplicación web adicionalmente somos libres de usar la API de geoposicionamiento implementada en los navegadores.

Proporcionar contenido personalizado al usuario probablemente ayuda a mejorar la conversión de un sitio de comercio electrónico y la experiencia del usuario ofreciéndole productos o servicios en los que de alguna forma esté interesado ya sea como en este caso basado en su ubicación, pero como en el caso de Amazon según las visitas anteriores y en otros podría ser en base al sistema operativo o navegador como hace Google cuando accedemos a su buscador indicándonos que nos instalemos Chrome si usamos Firefox.

Terminal

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando siguiente comando:
./gradlew run


Comparte el artículo: