Noticias Personalizadas
Lector de prensa bilingüe, autoalojado, sin fricción.
Resumen
Noticias Personalizadas es un lector de prensa personal que construí para mí mismo. Agrega artículos de pago de la prensa francesa (vía Europresse/BnF) y española (scraping directo), los presenta en modo lectura y los guarda en una biblioteca personal evaluable. Lo uso a diario desde su primer día de funcionamiento.
El problema
Me gusta leer la prensa seria en francés y en español. El problema no era el acceso —tengo acceso legítimo a Europresse a través de la BnF— sino la fricción. Cada artículo requería abrir Europresse, autenticarse, buscar, navegar. Ese coste de atención acumulado hacía que terminara no leyendo.
La solución no era leer menos. Era eliminar por completo la fricción de acceso.
La solución
El flujo es el corazón del proyecto: de la URL al modo lectura, en segundos, en dos idiomas.
- Pego una URL (o escribo palabras clave en modo francés) en la web, o comparto el artículo desde Safari con un atajo de iOS.
- Playwright automatiza el acceso en headless: en francés, autenticación en la BnF y búsqueda en Europresse; en español, acceso directo con bypass del paywall (El País) usando sesión persistente.
- Readability limpia el contenido y el artículo aparece en modo lectura —en menos de 15 segundos— listo para evaluar con me gusta / no me gusta.
Arquitectura
📱 iOS Shortcut 🌐 Web (Safari)
│ POST /add │
└──────────┬─────────┘
▼
⚙️ Flask (Hetzner VPS)
Google OAuth · cola de trabajos
│
┌──────────┴──────────┐
│ FR: palabras clave │ ES: URL directa
▼ ▼
🎭 Playwright 🎭 Playwright
BnF → Europresse bypass paywall
│ │
▼ ▼
📝 Texto limpio 📰 Readability
└──────────┬──────────┘
▼
🗄️ SQLite (articles.db)
like · dislike · tiempo · scroll
▼
📖 Lector personal El único paso manual es ejecutar el atajo. Todo lo demás es automático.
Stack técnico
| Capa | Tecnología |
|---|---|
| Automatización navegador | Playwright + Chromium (headless) |
| Extracción de contenido | readability-lxml (ES), extracción propia (FR) |
| Servidor web | Flask + SSE (progreso en tiempo real) |
| Almacenamiento | SQLite (gestión cuidadosa de conexiones) |
| Autenticación | Google OAuth 2.0 (Authlib) |
| Integración móvil | iOS Shortcuts → POST /add con token |
| Infraestructura | Hetzner VPS (Ubuntu) + Cloudflare Tunnel + systemd |
| Frontend | HTML/CSS/JS vanilla, mobile-first (Safari iOS) |
Retos técnicos resueltos
Automatización de autenticación en cadena
Playwright gestiona dos flujos de auth independientes —BnF/Europresse para francés, y El País con sesión persistente en JSON para español— sin intervención manual.
Extracción robusta contra CMS hostiles
Algunos sitios inyectan toolbars de editor en el DOM público. Implementé un pipeline de limpieza con filtros anti-basura CMS antes de Readability, con fallback por selectores de párrafo.
Proxy de imágenes con Referer
Las imágenes de El País están bloqueadas por CORS/Referer. Una ruta /api/img actúa de proxy servidor añadiendo el Referer correcto, con whitelist de dominios permitidos.
Integración iOS sin fricción
El endpoint /add responde en menos de 200 ms para que el atajo muestre la notificación al instante. Incluye deduplicación por URL y manejo del bug de iOS que duplica la URL en el POST.
Cola de trabajos con drenaje automático
Cuando el scraper está ocupado, los artículos se encolan. Al terminar cada scrape, el sistema retoma automáticamente los siguientes en cola, en secuencia, sin intervención manual.
Infraestructura de producción personal
El servicio corre como daemon systemd en un VPS, accesible desde cualquier lugar vía Cloudflare Tunnel HTTPS, con Google OAuth como capa de autenticación.
Resultados
- Uso diario desde el primer día — el proyecto resolvió un problema real y cambió un hábito.
- Dos fuentes completamente distintas unificadas en una sola interfaz bilingüe.
- Cero fricción de acceso: una URL compartida desde Safari → artículo en modo lectura en segundos.
- Base de datos personal evaluada, lista para alimentar un sistema de recomendación.
Qué demuestra este proyecto
Construí solo una herramienta de extremo a extremo —de la automatización de navegador a la infraestructura de producción— para resolver un problema cotidiano real. La motivación no era técnica: era recuperar el hábito de leer prensa seria, eliminando la fricción que lo impedía. El siguiente paso es el que más me interesa: usar el historial de evaluaciones para construir un recomendador que aprenda mis gustos.