Compartir en Twitter
Go to Homepage

OBTENER GEOLOCALIZACIÓN DE IP CON PYTHON

December 4, 2025

Introducción a la geolocalización de direcciones IP

En el mundo interconectado actual, determinar la ubicación geográfica de una dirección IP es una habilidad valiosa para desarrolladores, analistas de datos y profesionales de ciberseguridad. Desde personalizar experiencias de usuario hasta detectar actividades sospechosas, la geolocalización de IP permite extraer información como ciudad, país, latitud y longitud a partir de una dirección IP. Python, con su ecosistema de bibliotecas y APIs accesibles, ofrece herramientas poderosas para realizar esta tarea de manera eficiente. Este tutorial detalla cómo obtener información de geolocalización de una dirección IP utilizando Python, con ejemplos prácticos, mejores prácticas y enfoques actualizados al 2025.

La geolocalización de IP se basa en bases de datos que mapean direcciones IP a ubicaciones físicas. Estas bases de datos son mantenidas por proveedores de servicios y accesibles a través de APIs gratuitas o de pago. En este artículo, exploraremos cómo usar la API de ipapi.co, una opción gratuita y confiable, para obtener datos de geolocalización. También abordaremos cómo manejar errores, optimizar solicitudes y estructurar el código para proyectos reales.

Instalación de dependencias necesarias

Para interactuar con APIs de geolocalización, necesitamos la biblioteca requests de Python, que permite realizar solicitudes HTTP. Instalarla es sencillo usando pip, el administrador de paquetes de Python. Asegúrate de tener Python 3.8 o superior instalado en tu sistema.

pip install requests

Este comando instala la biblioteca requests en tu entorno. Si usas un entorno virtual, actívalo antes de ejecutar el comando. Verifica la instalación importando la biblioteca en un script de Python:

import requests
print(requests.__version__)

Si no hay errores, estás listo para continuar. La biblioteca requests es ligera y ampliamente utilizada para interactuar con APIs REST, como la que usaremos para la obtención de datos de IP.

Configuración del entorno de desarrollo

Organizar el proyecto es fundamental para mantener el código limpio y escalable. Recomendamos crear una estructura de directorios simple para almacenar scripts, configuraciones y datos. A continuación, un ejemplo de estructura:

proyecto-geolocalizacion-ip/
├── src/
│   └── geolocalizacion.py
├── data/
│   └── resultados.json
├── requirements.txt
└── README.md

El archivo requirements.txt debe incluir las dependencias del proyecto:

requests==2.32.3

Genera este archivo ejecutando:

pip freeze > requirements.txt

El directorio src contendrá el script principal, mientras que data almacenará los resultados de las consultas. Esta estructura es ideal para proyectos de análisis de direcciones IP y facilita la colaboración en equipos.

Uso de la API de ipapi.co

La API de ipapi.co ofrece un plan gratuito que permite hasta 1000 solicitudes diarias sin necesidad de autenticación para datos básicos de geolocalización. Proporciona información como ciudad, región, país, latitud, longitud y más. Para usarla, realizaremos una solicitud GET a su endpoint con la dirección IP deseada.

A continuación, un ejemplo de código que consulta la geolocalización de una IP:

import requests

def obtener_geolocalizacion(ip):
    url = f"https://ipapi.co/{ip}/json/"
    try:
        respuesta = requests.get(url)
        respuesta.raise_for_status()  # Lanza excepción si hay error HTTP
        datos = respuesta.json()
        if "error" in datos:
            return {"error": datos["reason"]}
        return {
            "ip": datos.get("ip"),
            "ciudad": datos.get("city"),
            "region": datos.get("region"),
            "pais": datos.get("country_name"),
            "latitud": datos.get("latitude"),
            "longitud": datos.get("longitude")
        }
    except requests.RequestException as e:
        return {"error": str(e)}

# Ejemplo de uso
ip = "8.8.8.8"
resultado = obtener_geolocalizacion(ip)
print(resultado)

Ejecutar este código produce una salida similar a:

{
    'ip': '8.8.8.8',
    'ciudad': 'Mountain View',
    'region': 'California',
    'pais': 'United States',
    'latitud': 37.751,
    'longitud': -122.4194
}

El código define una función obtener_geolocalizacion que toma una dirección IP como entrada, realiza una solicitud a la API y devuelve un diccionario con los datos relevantes. La gestión de errores asegura que el programa no falle si la API responde con un error o si hay problemas de conexión.

Manejo de errores y limitaciones

Las APIs gratuitas como ipapi.co tienen limitaciones, como cuotas de solicitudes diarias y posibles inexactitudes en los datos. Es crucial implementar un manejo robusto de errores para garantizar la estabilidad del programa. El ejemplo anterior usa un bloque try-except para capturar excepciones de red o errores HTTP.

Además, considera los siguientes casos:

  • Cuota excedida: La API puede devolver un error si superas el límite de 1000 solicitudes diarias. En este caso, el diccionario devuelto incluye una clave "error" con el motivo.

  • IP inválida: Si la IP no es válida, la API retorna un mensaje de error.

  • Datos faltantes: Algunos campos, como la ciudad, pueden estar vacíos para ciertas IPs.

Para manejar la cuota excedida, puedes implementar una espera entre solicitudes o usar una API alternativa como ipinfo.io (que requiere autenticación). Un ejemplo de espera entre solicitudes:

import time
import requests

def obtener_geolocalizacion_con_reintentos(ip, max_intentos=3):
    url = f"https://ipapi.co/{ip}/json/"
    for intento in range(max_intentos):
        try:
            respuesta = requests.get(url)
            respuesta.raise_for_status()
            datos = respuesta.json()
            if "error" in datos:
                if datos["reason"] == "RateLimited":
                    time.sleep(60)  # Espera 1 minuto
                    continue
                return {"error": datos["reason"]}
            return {
                "ip": datos.get("ip"),
                "ciudad": datos.get("city"),
                "region": datos.get("region"),
                "pais": datos.get("country_name"),
                "latitud": datos.get("latitude"),
                "longitud": datos.get("longitude")
            }
        except requests.RequestException as e:
            if intento == max_intentos - 1:
                return {"error": str(e)}
            time.sleep(2 ** intento)  # Backoff exponencial
    return {"error": "Máximo de intentos alcanzado"}

Este código reintenta la solicitud si la API indica que se excedió la cuota, esperando un minuto antes de volver a intentar. El manejo de errores robusto mejora la fiabilidad del programa.

Procesamiento de múltiples direcciones IP

En escenarios reales, es común necesitar geolocalizar múltiples direcciones IP, como las extraídas de un archivo de registros de servidor. Para ello, podemos leer una lista de IPs desde un archivo y procesarlas en lote. A continuación, un ejemplo:

import requests
import json

def leer_ips(archivo):
    with open(archivo, "r") as f:
        return [linea.strip() for linea in f if linea.strip()]

def geolocalizar_lote(ips):
    resultados = []
    for ip in ips:
        datos = obtener_geolocalizacion(ip)
        resultados.append(datos)
    return resultados

def guardar_resultados(resultados, archivo_salida):
    with open(archivo_salida, "w") as f:
        json.dump(resultados, f, indent=2, ensure_ascii=False)

# Ejemplo de uso
ips = leer_ips("data/ips.txt")
resultados = geolocalizar_lote(ips)
guardar_resultados(resultados, "data/resultados.json")

Supongamos que el archivo data/ips.txt contiene:

8.8.8.8
1.1.1.1

La ejecución genera un archivo data/resultados.json con:

[
  {
    "ip": "8.8.8.8",
    "ciudad": "Mountain View",
    "region": "California",
    "pais": "United States",
    "latitud": 37.751,
    "longitud": -122.4194
  },
  {
    "ip": "1.1.1.1",
    "ciudad": "Sydney",
    "region": "New South Wales",
    "pais": "Australia",
    "latitud": -33.8688,
    "longitud": 151.2093
  }
]

Este enfoque es eficiente para procesar listas de IPs y almacenar resultados en un formato estructurado como JSON, ideal para análisis posteriores.

Optimización de solicitudes a la API

Realizar múltiples solicitudes a una API puede ser lento y consumir la cuota rápidamente. Para optimizar, considera:

  • Almacenamiento en caché: Guarda los resultados de IPs ya consultadas en un archivo o base de datos para evitar solicitudes repetidas.
  • Solicitudes asíncronas: Usa la biblioteca aiohttp para realizar solicitudes simultáneas, reduciendo el tiempo de ejecución.

Un ejemplo de implementación con caché usando un diccionario persistente:

import requests
import json
import os

def cargar_cache(archivo_cache):
    if os.path.exists(archivo_cache):
        with open(archivo_cache, "r") as f:
            return json.load(f)
    return {}

def guardar_cache(cache, archivo_cache):
    with open(archivo_cache, "w") as f:
        json.dump(cache, f, indent=2)

def obtener_geolocalizacion_con_cache(ip, cache, archivo_cache):
    if ip in cache:
        return cache[ip]
    datos = obtener_geolocalizacion(ip)
    if "error" not in datos:
        cache[ip] = datos
        guardar_cache(cache, archivo_cache)
    return datos

# Ejemplo de uso
cache = cargar_cache("data/cache.json")
ips = ["8.8.8.8", "1.1.1.1"]
resultados = [obtener_geolocalizacion_con_cache(ip, cache, "data/cache.json") for ip in ips]
print(resultados)

El archivo data/cache.json almacenará los resultados, evitando consultas redundantes. Este método es útil para proyectos que manejan grandes volúmenes de datos de geolocalización.

Visualización de resultados en un mapa

Visualizar las ubicaciones en un mapa mejora la interpretación de los datos. La biblioteca folium permite crear mapas interactivos con Python. Instálala con:

pip install folium

A continuación, un ejemplo que genera un mapa con las ubicaciones de las IPs:

import folium

def crear_mapa(resultados, archivo_salida="mapa.html"):
    mapa = folium.Map(location=[0, 0], zoom_start=2)
    for datos in resultados:
        if "error" not in datos and datos["latitud"] and datos["longitud"]:
            folium.Marker(
                location=[datos["latitud"], datos["longitud"]],
                popup=f"{datos['ip']} - {datos['ciudad']}, {datos['pais']}"
            ).add_to(mapa)
    mapa.save(archivo_salida)

# Ejemplo de uso
resultados = [
    {"ip": "8.8.8.8", "ciudad": "Mountain View", "pais": "United States", "latitud": 37.751, "longitud": -122.4194},
    {"ip": "1.1.1.1", "ciudad": "Sydney", "pais": "Australia", "latitud": -33.8688, "longitud": 151.2093}
]
crear_mapa(resultados)

Este código genera un archivo mapa.html que muestra un mapa interactivo con marcadores en las ubicaciones de las IPs. La biblioteca folium es ideal para proyectos que requieren visualización de datos geoespaciales.

Mejores prácticas para proyectos reales

Para integrar la geolocalización de IP en aplicaciones reales, considera las siguientes recomendaciones:

  • Validación de IPs: Antes de enviar una solicitud, verifica que la IP sea válida usando expresiones regulares o la biblioteca ipaddress.
import ipaddress

def es_ip_valida(ip):
    try:
        ipaddress.ip_address(ip)
        return True
    except ValueError:
        return False

# Ejemplo
print(es_ip_valida("8.8.8.8"))  # True
print(es_ip_valida("256.1.2.3"))  # False
  • Uso de variables de entorno: Almacena claves de API (si usas una API que lo requiera) en variables de entorno para mayor seguridad.
import os
from dotenv import load_dotenv

load_dotenv()
API_KEY = os.getenv("API_KEY")
  • Monitoreo de cuotas: Registra el número de solicitudes realizadas para no exceder los límites de la API.
  • Escalabilidad: Para grandes volúmenes de datos, considera usar bases de datos como SQLite o PostgreSQL para almacenar resultados.

Consideraciones éticas y legales

La geolocalización de IP puede tener implicaciones de privacidad. Asegúrate de:

  • Cumplir con regulaciones como el GDPR si procesas datos de usuarios europeos.

  • Informar a los usuarios si sus IPs serán geolocalizadas.

  • Usar APIs confiables que respeten las normativas de privacidad.

Evita usar datos de geolocalización para fines no autorizados, como rastreo sin consentimiento. En contextos profesionales, documenta el propósito del uso de estos datos.

Conclusiones

La geolocalización de direcciones IP con Python es una técnica poderosa y accesible gracias a bibliotecas como requests y APIs como ipapi.co. Este tutorial cubrió desde la instalación de dependencias hasta la visualización de resultados en mapas interactivos, pasando por el manejo de errores, procesamiento en lote y optimización de solicitudes. Al implementar estas técnicas, los desarrolladores pueden crear aplicaciones robustas para análisis de tráfico web, ciberseguridad o personalización de contenido. Adoptar mejores prácticas, como la validación de IPs y el uso de caché, garantiza un código eficiente y escalable. Respetar las consideraciones éticas y legales es fundamental para un uso responsable de la geolocalización.