Procedimientos
Procedimientos
Problema a resolver:
Como seguidor de Félix Rodríguez de la Fuente deseaba guardarme todos los programas disponibles en RTVE de «La Aventura de la vida». Estos programas con ficheros mp3 y no están todos presentes en la web según carga, además dichos ficheros mp3 no tienen un titulo inteligible para mi, así que necesitaba bajarlos de forma automática y darle su titulo. Si programamos un script con python que haga estas tareas en unos 5 minutos lo tendremos.
Explicación de la solución:
Primero esperamos a que cargue la web y cerramos el banner de las cookies aceptándolas.
Después hay que pinchar en un botón «Ver Más» hasta que se vean todos los enlaces.
Después hago una tabla que contenga el enlace con el fichero mp3 y el titulo que le asignaré posteriormente al descargar.
Descargo todos los mp3 con el titulo que tiene asignado.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import os
import requests
# Configuración inicial
BASE_URL = "https://www.rtve.es/play/audios/la-aventura-de-la-vida/"
OUTPUT_DIR = "./mp3_files"
OUTPUT_TXT = "./mp3_links.txt"
# Crear la carpeta si no existe
os.makedirs(OUTPUT_DIR, exist_ok=True)
# Inicializar Selenium
driver = webdriver.Firefox() # Manteniendo el uso de Firefox
try:
# Cargar la página
driver.get(BASE_URL)
print("Página cargada.")
# Intentar cerrar el banner de cookies
try:
cookie_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "onetrust-accept-btn-handler"))
)
cookie_button.click()
print("Banner de cookies cerrado.")
except Exception as e:
print(f"No se encontró el banner de cookies o no se pudo hacer clic: {e}")
# Esperar la redirección si ocurre
time.sleep(3) # Esperar 3 segundos para que la redirección se complete
# Verificar la URL actual después de la redirección
current_url = driver.current_url
print(f"URL actual después de la redirección: {current_url}")
# Si la URL cambia a la página de radio, recargarla y continuar el proceso
if "rtve.es/play/radio" in current_url:
print("La página se redirigió a la página de radio.")
driver.get(current_url) # Recargar la página si es necesario
# Intentar hacer clic en el botón 'Ver más' repetidamente
while True:
try:
# Buscar todos los botones "Ver más" en la página
load_more_buttons = driver.find_elements(By.CSS_SELECTOR, "button.loadMore")
# Comprobar si hay algún botón "Ver más" visible
visible_buttons = [btn for btn in load_more_buttons if btn.is_displayed()]
if visible_buttons:
for button in visible_buttons:
print("Botón 'Ver más' encontrado, haciendo clic...")
button.click()
#time.sleep(3) # Esperar un poco para que carguen los nuevos elementos
else:
print("No hay más botones 'Ver más' visibles.")
break # Si no hay más botones visibles, salimos del bucle
except Exception as e:
print(f"Error al hacer clic en el botón 'Ver más': {e}")
break # Si no podemos hacer clic en el botón, salimos del bucle
# Encontrar los elementos que contienen los MP3
elementos = driver.find_elements(By.CSS_SELECTOR, "span.icon-label.extra.tooltip.blind.tres_botones[data-tipo='audio']")
print(f"Se encontraron {len(elementos)} elementos con enlaces MP3.")
mp3_links = set()
# Procesar cada uno de estos elementos
for i, elemento in enumerate(elementos):
try:
print(f"Procesando elemento {i + 1}/{len(elementos)}...")
# Desplazar hasta el elemento
driver.execute_script("arguments[0].scrollIntoView(true);", elemento)
# Encontrar el elemento <a> que está antes del <span> y extraer su 'title'
enlace = elemento.find_element(By.XPATH, "preceding-sibling::a")
title = enlace.get_attribute("title") # Extraemos el título del enlace
if title.startswith("Empezar a escuchar: "):
title = title.replace("Empezar a escuchar: ", "")
# Esperar a que el icono sea clickeable
icono = elemento.find_element(By.CSS_SELECTOR, ".rtve-icons")
WebDriverWait(driver, 10).until(EC.visibility_of(icono))
# Desplazar ligeramente para asegurarse de que no haya elementos cubriéndolo
driver.execute_script("window.scrollBy(0, -100);")
# Usar ActionChains para hacer clic
try:
icono.click()
print(f"Haciendo clic en el icono {i + 1}.")
except Exception as e:
print(f"Click normal falló, intentando con JavaScript... Error: {e}")
driver.execute_script("arguments[0].click();", icono)
# Esperar un poco más para asegurarse de que los enlaces MP3 se carguen después del clic
time.sleep(1) # Tiempo de espera adicional
# Buscar y procesar enlaces MP3 dentro del elemento con clase 'icon dwnld'
enlaces = driver.find_elements(By.CSS_SELECTOR, "span.icon.dwnld[data-file]")
if enlaces:
ultimo_enlace = enlaces[-1] # Tomar el último enlace encontrado
link = ultimo_enlace.get_attribute("data-file")
#link = enlace.get_attribute("data-file")
if link and link.endswith(".mp3"):
mp3_links.add((link, title)) # Asociamos el título con el enlace
print(f"Enlace MP3 encontrado: {link} - Título: {title}")
except Exception as e:
print(f"Error al procesar el elemento {i + 1}: {e}")
print(f"Se encontraron {len(mp3_links)} enlaces MP3 en total.")
finally:
driver.quit()
# Crear archivo de texto con la tabla de títulos y enlaces
with open(OUTPUT_TXT, "w", encoding="utf-8") as file:
file.write("Título\tEnlace\n")
for link, title in mp3_links:
file.write(f"{title}\t{link}\n")
print(f"Archivo de enlaces creado: {OUTPUT_TXT}")
# Descargar los archivos MP3
for link, title in mp3_links:
sanitized_title = "".join(c for c in title if c.isalnum() or c in (" ", "-", "_"))
filename = os.path.join(OUTPUT_DIR, f"{sanitized_title}.mp3")
if not os.path.exists(filename):
try:
print(f"Descargando {link} - Título: {title}...")
response = requests.get(link)
if response.status_code == 200:
with open(filename, "wb") as f:
f.write(response.content)
else:
print(f"Error al descargar {link}: Código de estado {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"Error al realizar la solicitud de descarga para {link}: {e}")
print(f"¡Descarga completa! Archivos guardados en {OUTPUT_DIR}.")









