Obtener precios de electricidad de OMIE con Python
Accede a precios de electricidad del mercado diario en tiempo real e históricos del operador del mercado eléctrico español—sin necesidad de API key.
Los precios de electricidad en España oscilan entre €10 y €200 por MWh en una sola semana. Con una simple función de Python, puedes obtener estos datos directamente de OMIE—sin necesidad de API key—y usarlos para análisis energético, optimización de baterías o previsión de costes.

En este artículo, construirás una función reutilizable para descargar cualquier rango de fechas con precios a resolución de 15 minutos para España y Portugal.
Preguntas
- ¿Dónde publica OMIE los datos de precios de electricidad?
- ¿Cómo descargar y parsear los precios de un solo día?
- ¿Cómo generalizar esto en una función reutilizable?
- ¿Cómo obtener múltiples días de forma eficiente?
- ¿Cuáles son los errores comunes a evitar?
Implementación
Encontrar los datos de OMIE
OMIE publica los datos del mercado en omie.es/es/file-access-list. Navega a:
- Mercado diario
- Precios del mercado diario en España
Los archivos siguen un patrón de nombres predecible: marginalpdbc_YYYYMMDD.1
Por ejemplo, los últimos precios del mercado diario podrían estar en: https://www.omie.es/es/file-download?parents=marginalpdbc&filename=marginalpdbc_20260112.1
Descargar un solo día
Empecemos descargando los precios de ayer directamente:
import pandas as pd
import requests
from datetime import datetime, timedelta
yesterday = datetime.now() - timedelta(days=1)
date_str = yesterday.strftime('%Y%m%d')
url = f"https://www.omie.es/es/file-download?parents=marginalpdbc&filename=marginalpdbc_{date_str}.1" Descarga: https://www.omie.es/es/file-download?parents=marginalpdbc&filename=marginalpdbc_20260111.1
Veamos el contenido sin procesar:
MARGINALPDBC; 2026;01;11;1;108.2;108.2; 2026;01;11;2;97.72;97.72; 2026;01;11;3;93.7;93.7; 2026;01;11;4;87.99;87.99; 2026;01;11;5;90;90;
Este es un archivo separado por punto y coma con una fila de cabecera (“MARGINALPDBC;”). El archivo contiene 96 filas - una por cada período de 15 minutos del día. Las columnas son año, mes, día, período (1-96), precio Portugal y precio España. Pandas puede leerlo directamente desde la URL:
df_raw = pd.read_csv(
url, sep=';', skiprows=1, header=None,
names=['year', 'month', 'day', 'period', 'price_portugal', 'price_spain', '_']
)
df_raw = df_raw.dropna(subset=['period'])
Parsear los datos
Cada período representa un intervalo de 15 minutos (período 1 = 00:00, período 2 = 00:15, etc.):
df_prices = df_raw[['period', 'price_spain', 'price_portugal']].copy()
df_prices['datetime'] = pd.to_datetime(yesterday.date()) + pd.to_timedelta((df_prices['period'] - 1) * 15, unit='m')
df_prices = df_prices.set_index('datetime')
Resumen de precios para 2026-01-11: - Mínimo: 50.25 €/MWh - Máximo: 108.20 €/MWh - Spread: 57.95 €/MWh
Visualizar el perfil diario

Crear una función reutilizable
Ahora envolvamos esto en una función que pueda obtener cualquier fecha:
def omie_day_ahead(date):
"""
Obtener precios de electricidad del mercado diario de OMIE para una fecha específica.
Parámetros:
date: objeto datetime
Devuelve:
DataFrame con columnas: period, price_spain, price_portugal (96 filas por día)
Devuelve None si los datos no están disponibles
"""
date_str = date.strftime('%Y%m%d')
url = f"https://www.omie.es/es/file-download?parents=marginalpdbc&filename=marginalpdbc_{date_str}.1"
try:
df = pd.read_csv(url, sep=';', skiprows=1, header=None,
names=['year', 'month', 'day', 'period', 'price_portugal', 'price_spain', '_'])
df = df.dropna(subset=['period'])
df['datetime'] = pd.to_datetime(date.date()) + pd.to_timedelta((df['period'] - 1) * 15, unit='m')
return df.set_index('datetime')[['period', 'price_spain', 'price_portugal']]
except Exception:
return None Probemos con algunas fechas diferentes:
df_yesterday = omie_day_ahead(datetime.now() - timedelta(days=1))
df_week_ago = omie_day_ahead(datetime.now() - timedelta(days=7))
df_future = omie_day_ahead(datetime.now() + timedelta(days=7)) - Ayer: 96 períodos (96 = 24 horas × 4)
- Hace una semana: 96 períodos
- Fecha futura: 0 períodos (esperado - los datos aún no están disponibles)
Obtener múltiples días
Para análisis que abarcan semanas o meses, necesitamos obtener un rango de fechas:
import time
def omie_day_ahead_range(start_date, end_date, delay=0.1):
"""
Obtener precios de OMIE para un rango de fechas.
Parámetros:
start_date: Primera fecha a obtener
end_date: Última fecha a obtener (inclusive)
delay: Segundos entre peticiones (sé amable con el servidor)
Devuelve:
DataFrame con todos los datos disponibles
"""
all_data = []
current = start_date
while current <= end_date:
df = omie_day_ahead(current)
if df is not None:
all_data.append(df)
current += timedelta(days=1)
time.sleep(delay)
if not all_data:
return None
return pd.concat(all_data) end = datetime.now() - timedelta(days=1)
start = end - timedelta(days=6)
df_week = omie_day_ahead_range(start, end) Obtenidos 672 períodos en 7 días.

Errores comunes
- Numeración de períodos: OMIE usa períodos 1-96 (intervalos de 15 minutos). Período 1 = 00:00, período 96 = 23:45.
- Disponibilidad de datos: Los precios del día D se publican alrededor de las 13:00 CET del día D-1. No intentes obtener los precios de hoy antes de que existan.
- Límite de peticiones: Añade retrasos entre peticiones cuando obtengas muchos días. OMIE puede bloquear scrapers agresivos.
- Cambios de horario: En los días de cambio de horario de verano/invierno, obtendrás 92 o 100 períodos en lugar de 96.
Conclusiones
Los datos de precios de electricidad de OMIE son accesibles gratuitamente mediante URLs predecibles:
- Un solo día:
https://www.omie.es/es/file-download?parents=marginalpdbc&filename=marginalpdbc_YYYYMMDD.1 - Formato: Separado por punto y coma, 96 períodos por día (resolución de 15 minutos)
- Cobertura: Precios del mercado diario de España y Portugal
Con estos datos, puedes construir aplicaciones de análisis energético: