TRAWL: Motor de scraping autoalojado que evita desafíos JS y CAPTCHAs

Publicado por


Motor de scraping autoalojado

TRAWL: Motor de scraping autoalojado que evita desafíos JS y CAPTCHAs

Alternativa a FlareSolverr y Byparr compatible con el ecosistema *arr, con enrutamiento adaptativo de 4 niveles y resolución nativa de CAPTCHAs

Vídeo tutorial en YouTube

Mira el vídeo completo sobre cómo instalar y usar TRAWL: Motor de scraping autoalojado que evita desafíos JS y CAPTCHAs en el canal GENBYTE:

¿Qué es TRAWL: Motor de scraping autoalojado que evita desafíos JS y CAPTCHAs?

TRAWL es un motor de scraping web autoalojado diseñado para aplicaciones y agentes de IA. Permite obtener páginas a través de su API nativa o conectar un cliente MCP para leer Markdown limpio, extraer datos estructurados, capturar capturas de pantalla e inspeccionar la actividad del navegador. Inicia con una petición HTTP rápida, reutiliza sesiones de navegador resueltas y escala a Camoufox y un proxy residencial opcional cuando un sitio requiere más trabajo. Maneja desafíos JavaScript y CAPTCHAs compatibles, y ofrece un panel de métricas local para ver qué tuvo éxito, qué falló y cuánto tardó. Para usuarios de FlareSolverr, el endpoint compatible /v1 funciona con Prowlarr y otras herramientas *arr. El enrutamiento adaptativo y la reutilización de sesiones de TRAWL están diseñados para peticiones más rápidas y fiables; benchmarks seleccionados en la misma máquina muestran respuestas más rápidas que FlareSolverr y Byparr, con resultados que varían según el sitio y el estado de la sesión.

Enrutamiento adaptativo de 4 niveles (HTTP plano → sesión cacheada → resolución fresca → proxy residencial) con reutilización de sesiones y resolución nativa de CAPTCHAs sin APIs de pago obligatorias

Características principales

Sesiones de navegador aisladas

Preservan cookies de login y localStorage entre peticiones de API nativa, MCP y FlareSolverr, con límites de capacidad y expiración automática por inactividad.

Herramientas MCP para agentes de IA

Leen páginas como Markdown o texto, extraen HTML, obtienen registros JSON, capturan capturas de pantalla e inspeccionan diagnósticos del navegador desde URLs públicas conocidas.

Ejecución de 4 niveles

Petición HTTP plana → sesión de navegador cacheada → resolución de desafío fresca → proxy residencial opcional.

Extracción estructurada y capturas de pantalla

Seleccionan campos de elementos repetidos, renderizan páginas con JavaScript y capturan viewport, página completa o elemento específico.

Proxy HTTP/HTTPS consciente de desafíos

Reenvío directo para tráfico normal, escalado automático de nivel para muros detectados, soporte WebSockets, cuerpos binarios y Range/206.

Panel de métricas local

Historial persistente de peticiones, resultados por nivel, causas de fallo y actualizaciones en vivo.

Manejo multi-WAF

Detección dedicada y flujos de navegador para Cloudflare, Akamai Bot Manager e Imperva/Incapsula.

Resolución nativa de CAPTCHAs

CF Turnstile/Interstitial, reCAPTCHA v2 (STT gratuito), hCaptcha checkbox/audio donde disponible, GeeTest Slide, ALTCHA, Friendly Captcha v1/v2 y prueba de trabajo CAP.

Camoufox Firefox

Firefox parcheado a nivel C++/Juggler para reducir señales de automatización.

Caché de sesiones

Cookies resueltas e identidad de navegador almacenadas en Redis; sesiones aceptadas pueden evitar una resolución fresca.

Compatible con FlareSolverr

Funciona con Prowlarr, Jackett, Sonarr y el ecosistema *arr completo sin configuración adicional.

Resolución local por defecto

No requiere API de solver de pago; fallback opcional a 2Captcha para reCAPTCHA v2/Enterprise y Turnstile independiente, con perfiles específicos por sitio para otros tipos de tareas documentados.

Requisitos del sistema

  • Docker y Docker Compose
  • Hardware moderno (imagen :latest) o CPU antigua sin AVX2 / kernels antiguos (imagen :baseline, probada en Synology DS920+ con Celeron J4125, DSM 7.3.2, kernel 4.4.302)
  • Mínimo 1 GB de memoria compartida (shm_size: 1gb en compose)
  • Redis 8.10 (incluido en docker-compose.yml por defecto) o modo memoria sin Redis
  • Puerto 8191 para API y 8192 para proxy MITM (opcional)

Instalación con Docker Compose

Clonar y configurar

Clona el repositorio y copia el archivo de entorno de ejemplo.

git clone https://github.com/germondai/trawl
cd trawl
cp .env.example .env

Iniciar con Docker Compose (scraper + Redis)

Usa el compose por defecto que incluye Redis y el scraper. El primer arranque tarda 15-30 segundos mientras se calienta el pool de navegadores.

docker compose up -d

Verificar salud

Comprueba que el servicio responde correctamente.

curl http://localhost:8191/health

Alternativa sin Redis (mínimo)

Usa docker-compose.minimal.yml para ejecutar solo el scraper sin Redis (caché en memoria).

docker compose -f docker-compose.minimal.yml up -d

Alternativa producción

Usa docker-compose.prod.yml con restart: always, límites de memoria y healthcheck.

docker compose -f docker-compose.prod.yml up -d

Seleccionar imagen según hardware

Imagen :latest para hardware moderno (requiere kernel 5.1+, 5.6+ recomendado). Imagen :baseline para CPUs antiguas sin AVX2, Synology NAS, kernels 3.10+.

# Moderno (la mayoría de usuarios)
image: ghcr.io/germondai/trawl:latest

# CPUs antiguas / Synology / kernels antiguos
image: ghcr.io/germondai/trawl:baseline

Acceder al proyecto

API nativa y endpoint FlareSolverr

Disponible en http://localhost:8191 (puerto configurable con PORT). Endpoints: POST /scrape (API nativa), POST /v1 (compatible FlareSolverr), GET /health, GET /proxy-ca.crt (certificado CA del proxy MITM).

Panel de métricas local

Accesible en http://localhost:8191/dashboard si METRICS_DASHBOARD_ENABLED=true. Requiere token de 32+ caracteres si el puerto es accesible fuera de localhost (METRICS_DASHBOARD_TOKEN).

Proxy MITM (opcional)

Escucha en puerto 8192 (MITM_PORT) cuando MITM_ENABLED=true. Por defecto enlaza en 0.0.0.0; usar MITM_HOST=127.0.0.1 para solo loopback. Requiere instalar el certificado CA en el almacén de confianza del cliente.

Integración con Prowlarr / Jackett / *arr

Configurar URL de FlareSolverr a http://localhost:8191 (mismo host) o http://trawl:8191 (misma red Docker). Para indexers que vinculan la clearance de Cloudflare a la huella del navegador, usar el proxy MITM como proxy HTTP en Prowlarr (host <trawl-host>, puerto 8192) tras instalar el CA.

Herramientas MCP

Disponibles en /mcp al establecer MCP_ENABLED=true. Compatibles con cualquier aplicación o agente compatible con MCP. Cargan URLs públicas conocidas; TRAWL no provee búsqueda web ni ranking.

Casos de uso

  • Scraping web para aplicaciones y agentes de IA con salida en Markdown, JSON estructurado, capturas de pantalla y diagnósticos de navegador
  • Integración directa con el ecosistema *arr (Prowlarr, Jackett, Sonarr, Radarr) como reemplazo drop-in de FlareSolverr/Byparr
  • Extracción de datos de sitios protegidos por Cloudflare, Akamai Bot Manager, Imperva/Incapsula y otros WAF
  • Resolución automatizada de CAPTCHAs (Turnstile, reCAPTCHA v2, hCaptcha, GeeTest, ALTCHA, Friendly Captcha, CAP proof-of-work) sin APIs de pago obligatorias
  • Proxy HTTP/HTTPS que evita desafíos para clientes que no pueden manejar cookies de navegador (Prowlarr, JDownloader, navegadores, clientes Java/.NET)
  • Monitoreo y depuración de scraping mediante panel de métricas local con historial persistente, resultados por nivel y causas de fallo

Configuración avanzada

Configuración de proxies upstream (Tier 3 y Tier 4)

Define proxies de datacenter (Tier 3) y residenciales (Tier 4) mediante variables de entorno. Soporta HTTP, HTTP autenticado y SOCKS5. Pools múltiples separados por comas o archivos con una URL por línea (PROXY_LIST_FILE, RESIDENTIAL_PROXY_LIST_FILE). Política de selección: failover (sticky por dominio), roundrobin o random (SCRAPE_PROXY_SELECTION).

# .env
PROXY_URL=http://user:[email protected]:8080
RESIDENTIAL_PROXY_URL=socks5://user:[email protected]:1080
SCRAPE_PROXY_SELECTION=failover

Proxy MITM para desafíos vinculados a huella de navegador

Algunos sitios vinculan la clearance de Cloudflare a la huella completa de la conexión del navegador que la resolvió. El endpoint /v1 no ayuda ahí porque Prowlarr re-hace la petición con su propio cliente HTTP. El proxy MITM de TRAWL resuelve esto: el cliente usa el proxy, TRAWL detecta desafíos y escala por los mismos niveles. Requiere instalar el CA generado en el almacén de confianza del cliente.

# .env
MITM_ENABLED=true
MITM_PORT=8192
MITM_CA_DIR=/data/proxy-ca
MITM_MAX_TIER=4
MITM_ALWAYS_SCRAPE=false
MITM_HOST=0.0.0.0

Instalación del certificado CA del proxy MITM

El proxy genera un CA raíz al primer inicio. Su certificado y clave persisten en MITM_CA_DIR. Cada cliente debe confiar en ese CA. Descargar: curl http://<trawl-host>:8191/proxy-ca.crt -o trawl-ca.crt. Instalar en Linux (Debian/Ubuntu): sudo cp trawl-ca.crt /usr/local/share/ca-certificates/trawl-ca.crt && sudo update-ca-certificates. En contenedores LinuxServer: montar el cert y script en /custom-cont-init.d/. En Java/JDownloader: keytool -importcert. En Windows: Import-Certificate. En Firefox: certutil -A. En macOS: security add-trusted-cert.

# Descargar CA
curl http://<trawl-host>:8191/proxy-ca.crt -o trawl-ca.crt
# O desde contenedor
docker cp trawl:/data/proxy-ca/ca.crt ./trawl-ca.crt

# Linux system-wide
sudo cp trawl-ca.crt /usr/local/share/ca-certificates/trawl-ca.crt
sudo update-ca-certificates

Habilitar herramientas MCP

Establece MCP_ENABLED=true para exponer herramientas Streamable HTTP independientes del cliente en /mcp. Permiten leer contenido legible, HTML, extracción estructurada, capturas de pantalla y diagnósticos de navegador a cualquier aplicación o agente compatible con MCP. Configura MCP_ALLOWED_ORIGINS para orígenes de navegador permitidos (peticiones sin Origin se aceptan).

# .env
MCP_ENABLED=true
MCP_ALLOWED_ORIGINS=https://tu-app.com

Panel de métricas con autenticación

Activa METRICS_DASHBOARD_ENABLED=true solo cuando el puerto esté enlazado a 127.0.0.1. Protege el panel, endpoint JSON y stream en vivo con token de 32+ caracteres (METRICS_DASHBOARD_TOKEN). La base de datos SQLite persiste en METRICS_DB_PATH (por defecto /data/metrics/trawl.sqlite, montar volumen persistentemente).

# .env
METRICS_DASHBOARD_ENABLED=true
METRICS_DASHBOARD_TOKEN=tu_token_de_al_menos_32_caracteres_aqui
METRICS_DB_PATH=/data/metrics/trawl.sqlite

Ajuste del pool de navegadores y reciclaje

BROWSER_POOL_SIZE: instancias calientes de Camoufox (subir para resoluciones concurrentes). BROWSER_MAX_CONTENT_PROCESSES: límite de procesos de contenido Firefox por navegador (reduce RAM/CPU). BROWSER_RECYCLE_AFTER_CONTEXTS: reciclado rodante tras N contextos Tier 3/4 (0 desactiva). BROWSER_ACQUIRE_TIMEOUT_MS: tiempo de espera para navegador libre antes de HTTP 429. BROWSER_SESSION_MAX_ENTRIES: contextos nombrados máximos por instancia (empezar con 1 en contenedores pequeños). BROWSER_SESSION_TTL_SECONDS: expiración por inactividad de sesiones nombradas.

# .env
BROWSER_POOL_SIZE=1
BROWSER_MAX_CONTENT_PROCESSES=2
BROWSER_RECYCLE_AFTER_CONTEXTS=8
BROWSER_ACQUIRE_TIMEOUT_MS=15000
BROWSER_SESSION_MAX_ENTRIES=4
BROWSER_SESSION_TTL_SECONDS=3600

Fallback a solver de CAPTCHA de pago (2Captcha)

Opcional. Una clave sola no lo activa. Automático para reCAPTCHA v2/Enterprise y Turnstile independiente. Otros tipos de tareas documentados necesitan perfiles por hostname con verificación explícita. CAPTCHA_SOLVER=2captcha, TWOCAPTCHA_API_KEY=tu_clave. Límites: CAPTCHA_SOLVER_MAX_TASKS (1-3, sin reintentos automáticos), timeouts locales y globales dentro del maxTimeout de la petición.

# .env
CAPTCHA_SOLVER=2captcha
TWOCAPTCHA_API_KEY=tu_clave_2captcha
CAPTCHA_SOLVER_MAX_TASKS=1
CAPTCHA_SOLVER_LOCAL_TIMEOUT_MS=10000
CAPTCHA_SOLVER_TIMEOUT_MS=120000

Gestión y mantenimiento

Healthcheck del contenedor

El compose por defecto incluye healthcheck que consulta /health cada 30s con timeout 10s, 3 reintentos y start_period de 90s. Redis tiene healthcheck propio con redis-cli ping cada 2s.

healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8191/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 90s

Actualización de imagen

TRAWL sigue versionado semántico. Las etiquetas :latest y :baseline se actualizan en cada release. Para fijar versión, usar etiqueta explícita (ej. ghcr.io/germondai/trawl:1.8.0). Los builds nightly (:nightly, :nightly-<sha>) se generan diariamente a las 02:00 UTC desde la rama dev. Para publicar un commit pasado con fix importante, etiquetar ese SHA exacto y hacer push.

# Actualizar a última versión
docker compose pull
docker compose up -d

# Fijar versión concreta en compose.yml
image: ghcr.io/germondai/trawl:1.8.0

# Publicar commit específico
git tag -a v1.0.1 <sha> -m "…"
git push origin v1.0.1

Persistencia de datos

Volúmenes nombrados en compose por defecto: redis_data (Redis), trawl_proxy_ca (CA del proxy MITM), trawl_metrics (SQLite de métricas). Montar /data/metrics y /data/proxy-ca persistentemente para conservar historial y certificado CA entre reinicios.

volumes:
– trawl_proxy_ca:${MITM_CA_DIR:-/data/proxy-ca}
– trawl_metrics:/data/metrics

Migración de configuración entre versiones

Actualizar desde versiones anteriores requiere renombrar varias variables de entorno. Consultar la guía de migración de configuración en la documentación oficial para el mapeo completo old-to-new y comportamiento de opt-in de Redis.

# Ver guía en:
# apps/docs/deployment/configuration-migration.md

Limpieza de certificado CA

El CA vive en <MITM_CA_DIR>/ca.crt y ca.key. Borrar cualquiera causa que TRAWL genere una nueva raíz al siguiente inicio, obligando a los clientes a reinstalar el certificado. Eliminar entradas del almacén de confianza buscando 'TRAWL MITM Proxy CA' (CN del CA).

# Linux system-wide
sudo rm /usr/local/share/ca-certificates/trawl-ca.crt
sudo update-ca-certificates

# Windows PowerShell (Admin)
Get-ChildItem Cert:\LocalMachine\Root | Where-Object { $_.Subject -like "*TRAWL MITM*" } | Remove-Item

Stack técnico

  • Runtime: Bun
  • API: Elysia
  • Navegador: Camoufox Firefox (via camoufox-js)
  • Caché de sesiones: Redis 8.8
  • Página de aterrizaje: Nuxt 4
  • Documentación: VitePress
  • Lenguaje principal: TypeScript
  • Gestión de paquetes: Bun workspaces
  • Linting/formateo: Biome
  • Contenedores: Docker (multi-arch, imágenes GHCR)

Apoya el canal GENBYTE

Sígueme en mis redes sociales

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *