¿Cómo obtener el país del que procede una IP?

Unos de nuestros clientes solicitó hace un tiempo la posibilidad de comprobar el páis de procedencia de los usuarios que accedían a su web, de manera que en función de si los usuarios accedían o no desde España se les presentaran distintas páginas web.

Para comprobar el país de procedencia, analizamos la IP del usuario y a partir de ella obtenemos el país asociado a la misma.

Para obtener el país a partir de la IP utilizamos dos opciones:

– Una se ejecuta del lado del servidor (ASP, PHP): IPINFODB –> http://www.ipinfodb.com

Para poder utilizar este método es necesario disponer de una clave que te proporcionan al registrarse.

– Otra se ejecuta del lado del cliente (JavaScript): Google AJAX API script –> http://www.google.com/jsapi

Inicialmente ejecutamos la primera opción. Si por lo que sea, esta opción no nos devuelve el país, entonces pasamos a ejecutar la segunda opción.

Hemos realizado dos implementaciones, una para ASP y otra para PHP.  Seguidamente se resumen ambas:

EJEMPLO COMPLETO EN ASP.  Está compuesto por tres archivos. La estructura que deben seguir y el código de cada uno es el que se indica a continuación:

index.asp

<%
Function Is_Mobile()
Set Regex = New RegExp
With Regex
.Pattern = "(up.browser|up.link|mmp|symbian|smartphone|midp|wap|phone|windows ce|pda|mobile|mini|palm|ipad)"
.IgnoreCase = True
.Global = True
End With
Match = Regex.test(Request.ServerVariables("HTTP_USER_AGENT"))
If Match then
Is_Mobile = True
Else
Is_Mobile = False
End If
End Function

If Is_Mobile() and request("movil") <> "1" then
response.redirect("http://www.ondarretacontract.com")
response.end()
End If
%>

Ondarreta
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
	<link href="css/nueva-home.css" rel="stylesheet" media="screen" type="text/css" />
	<link href="ondarreta.ico" rel="shortcut icon" />
<% 'Cargar fichero que comprueba el pais al que pertenece la IP del usuario actual. Si es un pais distinto a ESPAÑA, redireccionará al usuario a la página de ondarretacontract %>
<!--#include file="getLocalizacion.asp"-->
<% 'Comprobar si ya tenemos pais de localizacion, sino intentar obtenerlo mediante la api de google If Request.Cookies("adigeolocalizacion") = "" OR Request.Cookies("adigeolocalizacion") = "-" Then %>
<script type="text/javascript" src="http://www.google.com/jsapi"></script><script type="text/javascript" src="js/getLocalizacionIp.js"></script>
<script type="text/javascript">// <![CDATA[
checkPaisGeolocalizacion();
// ]]></script>
<% End if %></pre>
<div id="contenedor">
<ul>
	<li><a href="catalogo-ondarreta-hogar.asp"><img title="hola! kaixo! ola!" alt="hola! kaixo! ola!" src="images/hola.gif" /></a></li>
	<li><a href="http://www.ondarretacontract.com/en/home"><img title="hello! hallo! salut! oi! ni hau!" alt="hello! hallo! salut! oi! ni hau!" src="images/hello.gif" /></a></li>
</ul>
</div>
<pre>

getLocalizacion.asp

<%

Function obtenerPaisDeIp(UserIPAddress)
dim codigoPais
codigoPais = ""

If NOT UserIPAddress = "" then

Dim key
key = "bf97d1c01d0a0126fc02b8ce2cb0b8484d7c02eda5660af5e4c30c5233ff8fd2"

On Error Resume Next
Dim URL, objXML, value
Dim hayErrores
hayErrores = false

Set objXML = Server.CreateObject("MSXML2.DOMDocument.6.0")
URL = "http://api.ipinfodb.com/v3/ip-country/?key=" & key & "&ip=" & UserIPAddress & "&format=xml"

If (NOT Err.Description = "") then
hayErrores = true
Else
objXML.setProperty "ServerHTTPRequest", True
objXML.async = False
objXML.Load URL

'Resultado XML:
'
'    OK
'
'    88.12.19.13
'    ES
'    SPAIN
'

strStatusCode = objXML.documentElement.childNodes(0).text
strIpAddress = objXML.documentElement.childNodes(2).text
strCountryCode=objXML.documentElement.childNodes(3).text
value = objXML.documentElement.Text

if strStatusCode = "OK" then
hayErrores = false
codigoPais = strCountryCode
else
hayErrores = true
codigoPais = ""
end if

end if
End if

'Devolver el resultado
if codigoPais = "'" then
codigoPais = ""
end if
obtenerPaisDeIp = UCase(codigoPais)
End function

'IP del cliente:
'La instrucción Request.ServerVariables ("REMOTE_ADDR") puede ser usada para recuperar la IP de la máquina cliente. Pero, puestto que algunos cliente se conectan a Internet via proxy el método anterior sólo devolverá la IP del proxy y no la IP real del cliente.
'Con el fin de obtener la verdadera IP via el proxy server, pudes utilizar la instrucción Request.ServerVariables ("HTTP_X_FORWARDED_FOR").
'Nota: si el cliente no se conecta a Internet via un proxy,entonces la instrucción Request.ServerVariables ("HTTP_X_FORWARDED_FOR") devolverá un valor nulo.
Dim IPAddress
IPAddress = Request.ServerVariables("HTTP_X_FORWARDED_FOR")
If IPAddress = "" Then
IPAddress = Request.ServerVariables("REMOTE_ADDR")
End If

Dim codPais

'Comprobar si existe una coockie con su valor
If Request.Cookies("adigeolocalizacion") <> "" AND Request.Cookies("adigeolocalizacion") <> "-" Then
codPais = Request.Cookies("adigeolocalizacion")
'response.write("codigo pais en cookie:" & codPais & "
")
Else
'response.write("obtener codigo pais
")
'Obtener el pais al que pertenece la IP actual
codPais = obtenerPaisDeIp(IPAddress)
'response.write("codigo pais obtenido:" & codPais & "
")
if NOT codPais = "" then
'Crear cookie que caduque a los 7 días
Response.Cookies("adigeolocalizacion") = codPais
Response.Cookies("adigeolocalizacion").Expires = Date() + 7
end if
End if

if codPais <> "" AND codPais <> "-" AND codPais <> "ES" then
'Redireccionar de página
'response.write("Redireccionar a ondarreta contract")
response.redirect("http://www.ondarretacontract.com/en/home")
'elseif codPais = "" then
'    response.write("codigo vacio")
'else
'    response.write("estamos en españa")
End if

%>

js/getLocalizacionIp.js

//Función que comprueba si existe una cookie donde está almacenado el código al que pertenece la IP actual
function checkPaisGeolocalizacion(){
var codigo_pais_adigeolocalizacion = getCookie("adigeolocalizacion");
if (codigo_pais_adigeolocalizacion != null && codigo_pais_adigeolocalizacion != "" && codigo_pais_adigeolocalizacion != "-") {
//alert("Codigo pais en cookie: " + codigo_pais_adigeolocalizacion);
}
else {
//Obtener código del pais
codigo_pais_adigeolocalizacion = obtenerCodigoPais();
//alert("codigo pais obtenido:" + codigo_pais_adigeolocalizacion);
//Guardar en cookie dicho código
setCookie("adigeolocalizacion",codigo_pais_adigeolocalizacion,365);
}

//alert("codigo pais:" + codigo_pais_adigeolocalizacion);
if(codigo_pais_adigeolocalizacion != '' && codigo_pais_adigeolocalizacion != '-' && codigo_pais_adigeolocalizacion != 'ES'){
//Redireccionar de página
//alert("Redireccionar a ondarreta contract");
window.location.href = "http://www.ondarretacontract.com/en/home";
}
}

function obtenerCodigoPais(){

var visitor_countrycode = "";
if(google.loader.ClientLocation) {
/*
visitor_lat = google.loader.ClientLocation.latitude;
visitor_lon = google.loader.ClientLocation.longitude;
visitor_city = google.loader.ClientLocation.address.city;
visitor_region = google.loader.ClientLocation.address.region;
visitor_country = google.loader.ClientLocation.address.country;
visitor_countrycode = google.loader.ClientLocation.address.country_code;
document.getElementById('yourinfo').innerHTML = '

Lat/Lon: ' + visitor_lat + ' / ' + visitor_lon + '

Location: ' + visitor_city + ', ' + visitor_region + ', ' + visitor_country + ' (' + visitor_countrycode + ')

';
*/
visitor_countrycode = google.loader.ClientLocation.address.country_code;
//document.getElementById('yourinfo').innerHTML = 'Codigo pais:' + visitor_countrycode;
visitor_countrycode = visitor_countrycode.toUpperCase();
}

return visitor_countrycode;
}

function getCookie(c_name){
var c_value = document.cookie;
var c_start = c_value.indexOf(" " + c_name + "=");
if (c_start == -1)
{
c_start = c_value.indexOf(c_name + "=");
}
if (c_start == -1)
{
c_value = null;
}
else
{
c_start = c_value.indexOf("=", c_start) + 1;
var c_end = c_value.indexOf(";", c_start);
if (c_end == -1)
{
c_end = c_value.length;
}
c_value = unescape(c_value.substring(c_start,c_end));
}
return c_value;
}

function setCookie(c_name,value,exdays){
var exdate=new Date();
exdate.setDate(exdate.getDate() + exdays);
var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString());
document.cookie=c_name + "=" + c_value;
}

Clases a utilizar para ejemplos en  PHP:

pruebaGeo.php (Google_Jsapi)

<!--?php <br ?-->/*
$host = $_SERVER['REMOTE_ADDR'];
$host = "88.12.19.13";
echo("Remote address:" . $host . "
");
$ip = @gethostbyname($host);
echo("IP:" . $ip . "
");
*/

//ipinfodb
//http://api.ipinfodb.com/v3/ip-country/?key=<your_api_key>&ip=74.125.45.100
//We do not have a specific daily limit but queries that are at a rate faster than 2 per second will be put in "queue".
//If you stay below 2 queries/second everything will be normal. If you go over the limit, you will still get an answer for all queries but they will be slowed down to about 1 per second.
?>
<!--?php include('ip2locationlite.class.php');?-->
<!--?php function obtenerPaisDeIp($UserIPAddress){ //Load the class $ipLite = new ip2location_lite; $ipLite--->setKey('bf97d1c01d0a0126fc02b8ce2cb0b8484d7c02eda5660af5e4c30c5233ff8fd2');

//Get errors and locations
$mi_ip = $UserIPAddress;
$visitorGeolocation = $ipLite->getCountry($mi_ip);
//var_dump($visitorGeolocation);

$pais_resultado = "";
if ($visitorGeolocation['statusCode'] == 'OK') {
$pais_resultado = $visitorGeolocation["countryCode"];
}
return $pais_resultado;
}

if(!isset($_COOKIE['adigeolocalizacion']) || (isset($_COOKIE['adigeolocalizacion']) && ($_COOKIE['adigeolocalizacion'] == "" || $_COOKIE['adigeolocalizacion'] == "-"))){
$mi_ip = $_SERVER['REMOTE_ADDR'];
$mi_ip = "88.12.19.13";
$visitorGeolocationPais = obtenerPaisDeIp($mi_ip);
//echo("pais obtenido:" . $visitorGeolocationPais . "--guardarlo en cookie
");

//Guardar el dato en cookie
setcookie("adigeolocalizacion", $visitorGeolocationPais, time()+3600*24*7); //set cookie for 1 week
}
else{
$visitorGeolocationPais = $_COOKIE["adigeolocalizacion"];
}
?>

Obtener pais asociado a IP cliente
<meta name="robots" />

</pre>
<div>
<!--?php echo("codigo pais:" . $visitorGeolocationPais . "<br ?-->");?></div>
<pre>

ip2locationlite.class.php

<!--?php final class ip2location_lite{ protected $errors = array(); protected $service = 'api.ipinfodb.com'; protected $version = 'v3'; protected $apiKey = ''; public function __construct(){} public function __destruct(){} public function setKey($key){ if(!empty($key)) $this--->apiKey = $key;
}

public function getError(){
return implode("\n", $this->errors);
}

public function getCountry($host){
return $this->getResult($host, 'ip-country');
}

public function getCity($host){
return $this->getResult($host, 'ip-city');
}

private function getResult($host, $name){
$ip = @gethostbyname($host);

if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)){
$xml = @file_get_contents('http://' . $this->service . '/' . $this->version . '/' . $name . '/?key=' . $this->apiKey . '&ip=' . $ip . '&format=xml');

if (get_magic_quotes_runtime()){
$xml = stripslashes($xml);
}

try{
$response = @new SimpleXMLElement($xml);

foreach($response as $field=>$value){
$result[(string)$field] = (string)$value;
}

return $result;
}
catch(Exception $e){
$this->errors[] = $e->getMessage();
return;
}
}

$this->errors[] = '"' . $host . '" is not a valid IP address or hostname.';
return;
}
}

NOTA:
Hay que tener en cuenta que la geolocalización por IP no es fiable al 100% debido básicamente a que existen rangos de IP’s que se venden o alquilan entre operadoras según necesidades por lo que no siempre el país devuelto es el correcto.

Deja un comentario