n8n Playwright: Automatización Web Nativa sin Browserless (Guía Completa 2025)
📋 TL;DR
El nodo Playwright nativo de n8n te permite automatizar navegadores web directamente desde tus workflows, sin necesidad de Docker, Browserless ni servicios externos. En esta guía completa aprenderás a usar este nodo para scraping, automatización de formularios, capturas de pantalla y mucho más, con 10+ ejemplos prácticos listos para copiar.
Lo que conseguirás:
- ✅ Automatizar navegadores web sin complejidad adicional
- ✅ Crear workflows de scraping y automatización funcionales
- ✅ Entender cuándo usar el nodo nativo vs Browserless
- ✅ Resolver errores comunes y optimizar performance
Tiempo de lectura: ~25 minutos | Nivel: Intermedio
—📚 Tabla de Contenidos
- [Introducción](#introduccion)
- [¿Qué es el Nodo Playwright Nativo de n8n?](#que-es)
- [Comparativa: Nativo vs Browserless](#comparativa)
- [Instalación y Configuración](#instalacion)
- [Acciones y Funcionalidades](#acciones)
- [10+ Ejemplos Prácticos](#ejemplos)
- [Mejores Prácticas](#mejores-practicas)
- [Troubleshooting Común](#troubleshooting)
- [Integración con Otros Nodos](#integracion)
- [Casos de Uso Avanzados](#casos-avanzados)
- [Preguntas Frecuentes](#faq)
- [Conclusión](#conclusion)
> 📅 Última actualización: Noviembre 2025
> ✅ Verificado con: n8n v1.0+
> 🔄 Próxima revisión: Febrero 2026
—Introducción
¿Necesitas automatizar tareas web pero Browserless te parece demasiado complejo? ¿Quieres hacer scraping, rellenar formularios o capturar pantallas sin configurar Docker ni servicios externos?
El nodo Playwright nativo de n8n es la solución perfecta: una integración built-in que te permite automatizar navegadores web directamente desde tus workflows, sin dependencias adicionales ni configuración compleja.
Problema que resuelve:
Automatizar tareas web tradicionalmente requiere servicios externos como Browserless, configuración de Docker, gestión de recursos y mantenimiento de servicios separados. Esto añade complejidad innecesaria para casos de uso simples.
La solución:
El nodo Playwright nativo de n8n elimina toda esta complejidad. Está incluido en n8n, no requiere instalación adicional y funciona directamente en tu servidor, consumiendo recursos de forma eficiente.
En esta guía completa aprenderás:
- Qué es el nodo Playwright nativo y cómo funciona
- Cuándo usarlo vs Browserless (con tabla comparativa)
- Cómo instalarlo y configurarlo paso a paso
- Todas las acciones disponibles (navegación, interacción, extracción)
- 10+ ejemplos prácticos listos para copiar
- Mejores prácticas de performance y seguridad
- Troubleshooting de errores comunes
- Integración con otros nodos de n8n
Ya seas desarrollador, DevOps o entusiasta de la automatización, esta guía te dará las herramientas para crear workflows web potentes y simples.
—¿Qué es el Nodo Playwright Nativo de n8n?
Definición y Características
El nodo Playwright nativo de n8n es una integración built-in que permite automatizar navegadores web directamente desde workflows de n8n, sin necesidad de servicios externos como Browserless.
Características principales:
- ✅ Integración nativa: Incluido en n8n, no requiere instalación adicional
- ✅ Sin dependencias externas: No necesita Docker, Browserless ni servicios separados
- ✅ Ejecución local: Corre directamente en el servidor donde está n8n
- ✅ Acceso directo a Playwright: API completa de Playwright disponible
- ✅ Integración perfecta: Funciona sin problemas con otros nodos de n8n
- ✅ Sin configuración: Funciona out-of-the-box después de instalar n8n
¿Cuándo se Introdujo?
El nodo Playwright nativo está disponible en n8n desde la versión 1.0+ (2024). Si tu versión de n8n es anterior, necesitarás actualizar para acceder a esta funcionalidad.
Ventajas sobre Alternativas
vs Browserless:
- ✅ Sin Docker ni servicios externos
- ✅ Configuración cero
- ✅ Latencia mínima (ejecución local)
- ✅ Mantenimiento automático (se actualiza con n8n)
vs Puppeteer/Selenium:
- ✅ Integración visual en n8n
- ✅ Sin código JavaScript complejo
- ✅ Gestión automática de recursos
- ✅ Integración con otros nodos
Comparativa: Nativo vs Browserless

Antes de decidir qué usar, es crucial entender las diferencias entre el nodo Playwright nativo y Browserless.
Tabla Comparativa Completa
| Aspecto | Nodo Playwright Nativo | Browserless + Playwright |
|---|---|---|
| Instalación | ✅ Incluido en n8n | ❌ Requiere Docker + Browserless |
| Configuración | ✅ Cero configuración | ❌ Configurar servicio externo |
| Recursos | ⚠️ Consume recursos del servidor n8n | ✅ Aislado en contenedor |
| RAM por instancia | ~200-400MB | ~100MB (con pooling) |
| Startup time | 2-3 segundos | ~0.1s (pre-warm) |
| Escalabilidad | ⚠️ Limitada por recursos del servidor | ✅ Escalable independientemente |
| Aislamiento | ❌ Comparte recursos con n8n | ✅ Aislado en contenedor |
| Mantenimiento | ✅ Automático (actualiza con n8n) | ❌ Mantener servicio separado |
| Costo | ✅ Gratis (self-hosted) | ⚠️ Cloud puede costar |
| Latencia | ✅ Muy baja (local) | ⚠️ Depende de red |
| Pooling | ❌ No disponible | ✅ Sí (eficiencia) |
| Métricas | ⚠️ Limitadas | ✅ Prometheus/Grafana |
| Complejidad | ✅ Simple | ❌ Más complejo |
Cuándo Usar Cada Uno
Usar Nodo Nativo cuando:
- ✅ Necesitas automatización web simple y rápida
- ✅ Tienes recursos suficientes en tu servidor n8n (4GB+ RAM)
- ✅ No necesitas escalar a múltiples instancias simultáneas
- ✅ Quieres evitar la complejidad de Docker/Browserless
- ✅ Trabajas con workflows de bajo volumen (<10 ejecuciones/hora)
- ✅ Priorizas simplicidad sobre escalabilidad
Casos de uso ideales:
- Scraping ocasional de sitios web
- Automatización de formularios simples
- Capturas de pantalla para reportes
- Generación de PDFs bajo demanda
- Prototipado rápido de workflows
Usar Browserless cuando:
- ✅ Necesitas escalar a muchas instancias simultáneas (>10/hora)
- ✅ Quieres aislar el consumo de recursos del navegador
- ✅ Tienes múltiples servicios que necesitan automatización web
- ✅ Necesitas pooling de navegadores para eficiencia
- ✅ Trabajas con alto volumen de automatizaciones (>100/hora)
- ✅ Requieres métricas detalladas (Prometheus)
Casos de uso ideales:
- Scraping masivo de múltiples sitios
- Testing automatizado a escala
- Monitoreo continuo de sitios web
- Producción con alta carga
- Múltiples servicios compartiendo recursos
Decision Matrix
¿Necesitas >10 ejecuciones/hora simultáneas?
├─ SÍ → Browserless
└─ NO → ¿Tienes 4GB+ RAM libres?
├─ SÍ → Nodo Nativo
└─ NO → Browserless (aislamiento)
—
Instalación y Configuración

Requisitos Previos
Versión de n8n:
- n8n versión 1.0.0 o superior (recomendado: última versión estable)
Sistema Operativo:
- Linux (recomendado)
- macOS
- Windows (con limitaciones)
Dependencias del Sistema:
- Node.js (incluido en n8n)
- Playwright browsers (se instalan automáticamente la primera vez)
Recursos del Sistema:
- RAM: Mínimo 2GB libres (recomendado 4GB+)
- CPU: 2+ cores recomendados
- Disco: ~500MB para navegadores Playwright
Verificación de Disponibilidad
El nodo Playwright debería estar disponible por defecto en versiones recientes de n8n. Para verificar:
- Abre n8n
- Crea un nuevo workflow
- Busca «Playwright» en la paleta de nodos
- Si aparece, está disponible ✅
Si no aparece:
- Verifica tu versión de n8n:
n8n --version - Actualiza a la última versión:
npm install -g n8n@latest - Reinicia n8n
- Verifica que no esté deshabilitado en configuración
Instalación de Navegadores Playwright
La primera vez que uses el nodo Playwright, n8n intentará instalar los navegadores automáticamente. Si esto falla, puedes instalarlos manualmente:
# En el servidor donde corre n8n
npx playwright install chromium
Esto instalará Chromium (~170MB) que es suficiente para la mayoría de casos de uso.
Configuración Inicial
Pasos básicos:
- Abrir n8n y crear nuevo workflow
- Añadir nodo Playwright desde la paleta
- Configurar acción según necesidad (goto, click, etc.)
- Ejecutar workflow para probar
Primer workflow de prueba:
1. Trigger (Manual)
2. Playwright Node:
- Action: goto
- URL: https://example.com
3. Playwright Node:
- Action: getText
- Selector: h1
4. Output: Ver texto extraído
—
Acciones y Funcionalidades

El nodo Playwright nativo de n8n ofrece todas las acciones principales de Playwright. Aquí está la lista completa:
Navegación
goto – Navegar a URL
Navega a una URL específica.
Configuración:
- URL:
https://example.com - Wait Until:
load(default),domcontentloaded,networkidle - Timeout: 30000ms (default)
Ejemplo:
{
"action": "goto",
"url": "https://www.eldiarioia.es",
"waitUntil": "networkidle"
}
goBack – Volver a Página Anterior
Vuelve a la página anterior en el historial del navegador.
Ejemplo:
{
"action": "goBack"
}
goForward – Avanzar a Página Siguiente
Avanza a la página siguiente en el historial.
Ejemplo:
{
"action": "goForward"
}
reload – Recargar Página
Recarga la página actual.
Ejemplo:
{
"action": "reload",
"waitUntil": "networkidle"
}
Interacción
click – Hacer Clic en Elemento
Hace clic en un elemento de la página.
Configuración:
- Selector: CSS selector o XPath
- Button:
left(default),right,middle - Click Count: 1 (default)
- Timeout: 30000ms
Ejemplo:
{
"action": "click",
"selector": "button[type='submit']",
"button": "left"
}
fill – Rellenar Campo de Formulario
Rellena un campo de formulario con texto.
Configuración:
- Selector: CSS selector del campo
- Text: Texto a escribir
- Timeout: 30000ms
Ejemplo:
{
"action": "fill",
"selector": "#email",
"text": "{{ $json.email }}"
}
selectOption – Seleccionar Opción en Dropdown
Selecciona una opción en un elemento .
Configuración:
- Selector: CSS selector del
- Value: Valor de la opción a seleccionar
- Label: Texto visible de la opción (alternativa a value)
Ejemplo:
{
"action": "selectOption",
"selector": "#category",
"value": "technology"
}
check – Marcar Checkbox
Marca un checkbox.
Ejemplo:
{
"action": "check",
"selector": "#accept-terms"
}
uncheck – Desmarcar Checkbox
Desmarca un checkbox.
Ejemplo:
{
"action": "uncheck",
"selector": "#newsletter"
}
press – Presionar Tecla
Presiona una tecla específica.
Teclas comunes:
Enter,Escape,Tab,ArrowUp,ArrowDown,ArrowLeft,ArrowRightBackspace,Delete,Home,End,PageUp,PageDown
Ejemplo:
{
"action": "press",
"key": "Enter"
}
type – Escribir Texto
Escribe texto carácter por carácter (simula escritura humana).
Ejemplo:
{
"action": "type",
"selector": "#search",
"text": "n8n automation",
"delay": 100
}
Extracción de Datos
getText – Obtener Texto de Elemento
Extrae el texto visible de un elemento.
Ejemplo:
{
"action": "getText",
"selector": "h1"
}
Output:
{
"text": "Título de la Página"
}
getAttribute – Obtener Atributo
Obtiene el valor de un atributo HTML.
Ejemplo:
{
"action": "getAttribute",
"selector": "a.link",
"attribute": "href"
}
Output:
{
"value": "https://example.com/page"
}
screenshot – Capturar Pantalla
Captura una imagen de la página.
Configuración:
- Path: Ruta donde guardar (opcional, si no se especifica retorna base64)
- Full Page:
truepara capturar toda la página - Type:
png(default) ojpeg - Quality: 0-100 (solo para JPEG)
Ejemplo:
{
"action": "screenshot",
"fullPage": true,
"type": "png"
}
pdf – Generar PDF
Genera un PDF de la página actual.
Configuración:
- Path: Ruta donde guardar (opcional)
- Format:
A4(default),Letter, etc. - Print Background:
truepara incluir fondos
Ejemplo:
{
"action": "pdf",
"format": "A4",
"printBackground": true
}
evaluate – Ejecutar JavaScript
Ejecuta JavaScript en el contexto de la página.
Ejemplo:
{
"action": "evaluate",
"expression": "() => document.title"
}
Ejemplo avanzado (extraer tabla):
{
"action": "evaluate",
"expression": "() => Array.from(document.querySelectorAll('table tr')).map(row => Array.from(row.querySelectorAll('td')).map(cell => cell.textContent))"
}
Esperas
waitForSelector – Esperar Selector
Espera a que un selector aparezca en la página.
Configuración:
- Selector: CSS selector o XPath
- State:
visible(default),hidden,attached,detached - Timeout: 30000ms
Ejemplo:
{
"action": "waitForSelector",
"selector": ".content-loaded",
"state": "visible"
}
waitForNavigation – Esperar Navegación
Espera a que la página navegue (después de un click, por ejemplo).
Configuración:
- Wait Until:
load,domcontentloaded,networkidle - Timeout: 30000ms
Ejemplo:
{
"action": "waitForNavigation",
"waitUntil": "networkidle"
}
waitForLoadState – Esperar Estado de Carga
Espera a que la página alcance un estado de carga específico.
Estados:
load: Espera eventoloaddomcontentloaded: Espera DOM listonetworkidle: Espera a que no haya requests de red por 500ms
Ejemplo:
{
"action": "waitForLoadState",
"state": "networkidle"
}
—
10+ Ejemplos Prácticos
Ejemplo 1: Scraping Básico de Página Web
Caso de uso: Extraer título y contenido principal de una página web.
Workflow:
1. Trigger (Manual o Schedule)
2. Playwright Node (goto):
- Action: goto
- URL: https://example.com
3. Playwright Node (getTitle):
- Action: getText
- Selector: h1
4. Playwright Node (getContent):
- Action: getText
- Selector: p.article-content
5. Code Node (format):
- Procesar y formatear datos
6. Output: Datos extraídos
Configuración detallada:
Nodo 2 – goto:
{
"action": "goto",
"url": "https://example.com",
"waitUntil": "networkidle"
}
Nodo 3 – getTitle:
{
"action": "getText",
"selector": "h1"
}
Nodo 4 – getContent:
{
"action": "getText",
"selector": "p.article-content"
}
Nodo 5 – Code (formatear):
const title = $input.item.json.text; // Del nodo getTitle
const content = $input.item.json.text; // Del nodo getContent
return {
title: title.trim(),
content: content.trim(),
extractedAt: new Date().toISOString()
};
Ejemplo 2: Automatización de Formulario
Caso de uso: Rellenar y enviar un formulario de contacto automáticamente.
Workflow:
1. Trigger (Webhook o Schedule)
2. Playwright Node (goto):
- Action: goto
- URL: https://example.com/contact
3. Playwright Node (fillName):
- Action: fill
- Selector: #name
- Text: {{ $json.name }}
4. Playwright Node (fillEmail):
- Action: fill
- Selector: #email
- Text: {{ $json.email }}
5. Playwright Node (fillMessage):
- Action: fill
- Selector: #message
- Text: {{ $json.message }}
6. Playwright Node (submit):
- Action: click
- Selector: button[type="submit"]
7. Playwright Node (waitSuccess):
- Action: waitForSelector
- Selector: .success-message
8. Output: Confirmación
Configuración:
Nodo 2 – goto:
{
"action": "goto",
"url": "https://example.com/contact"
}
Nodo 3 – fillName:
{
"action": "fill",
"selector": "#name",
"text": "{{ $json.name }}"
}
Nodo 4 – fillEmail:
{
"action": "fill",
"selector": "#email",
"text": "{{ $json.email }}"
}
Nodo 5 – fillMessage:
{
"action": "fill",
"selector": "#message",
"text": "{{ $json.message }}"
}
Nodo 6 – submit:
{
"action": "click",
"selector": "button[type='submit']"
}
Nodo 7 – waitSuccess:
{
"action": "waitForSelector",
"selector": ".success-message",
"state": "visible",
"timeout": 10000
}
Ejemplo 3: Captura de Pantalla
Caso de uso: Generar screenshot de un dashboard para reporte diario.
Workflow:
1. Trigger (Schedule diario a las 9:00 AM)
2. Playwright Node (goto):
- Action: goto
- URL: https://dashboard.example.com
3. Playwright Node (waitLoad):
- Action: waitForLoadState
- State: networkidle
4. Playwright Node (screenshot):
- Action: screenshot
- Full Page: true
- Type: png
5. HTTP Request Node (upload):
- Subir imagen a S3/Google Drive
6. Telegram Node (notify):
- Enviar notificación con imagen
Configuración:
Nodo 2 – goto:
{
"action": "goto",
"url": "https://dashboard.example.com",
"waitUntil": "networkidle"
}
Nodo 3 – waitLoad:
{
"action": "waitForLoadState",
"state": "networkidle"
}
Nodo 4 – screenshot:
{
"action": "screenshot",
"fullPage": true,
"type": "png"
}
Output del screenshot:
El nodo retorna la imagen en base64 que puedes usar directamente en otros nodos.
Ejemplo 4: Generación de PDF
Caso de uso: Convertir una página web a PDF para archivo.
Workflow:
1. Trigger (Webhook con URL)
2. Playwright Node (goto):
- Action: goto
- URL: {{ $json.url }}
3. Playwright Node (waitLoad):
- Action: waitForLoadState
- State: networkidle
4. Playwright Node (pdf):
- Action: pdf
- Format: A4
- Print Background: true
5. HTTP Request Node (email):
- Enviar PDF por email
Configuración:
Nodo 2 – goto:
{
"action": "goto",
"url": "{{ $json.url }}"
}
Nodo 4 – pdf:
{
"action": "pdf",
"format": "A4",
"printBackground": true
}
Ejemplo 5: Scraping de Tabla HTML
Caso de uso: Extraer datos de una tabla HTML y guardarlos en base de datos.
Workflow:
1. Trigger (Schedule cada hora)
2. Playwright Node (goto):
- Action: goto
- URL: https://example.com/data
3. Playwright Node (extractTable):
- Action: evaluate
- Expression: (ver código abajo)
4. Code Node (process):
- Procesar datos extraídos
5. Database Node (save):
- Guardar en PostgreSQL/MySQL
Nodo 3 – extractTable (evaluate):
() => {
const rows = Array.from(document.querySelectorAll('table tr'));
return rows.map(row => {
const cells = Array.from(row.querySelectorAll('td, th'));
return cells.map(cell => cell.textContent.trim());
});
}
Nodo 4 – Code (process):
const tableData = $input.item.json;
// Filtrar header (primera fila)
const headers = tableData[0];
const rows = tableData.slice(1);
// Convertir a objetos
const records = rows.map(row => {
const record = {};
headers.forEach((header, index) => {
record[header.toLowerCase().replace(/\s+/g, '_')] = row[index];
});
return record;
});
return records;
Ejemplo 6: Login Automatizado
Caso de uso: Iniciar sesión en un sitio web y acceder a contenido protegido.
Workflow:
1. Trigger (Schedule diario)
2. Playwright Node (gotoLogin):
- Action: goto
- URL: https://example.com/login
3. Playwright Node (fillUsername):
- Action: fill
- Selector: #username
- Text: {{ $env.USERNAME }}
4. Playwright Node (fillPassword):
- Action: fill
- Selector: #password
- Text: {{ $env.PASSWORD }}
5. Playwright Node (submit):
- Action: click
- Selector: button[type="submit"]
6. Playwright Node (waitNav):
- Action: waitForNavigation
7. Playwright Node (gotoDashboard):
- Action: goto
- URL: https://example.com/dashboard
8. Playwright Node (extractData):
- Action: getText
- Selector: .dashboard-content
⚠️ Seguridad: Usa variables de entorno ($env.USERNAME, $env.PASSWORD) nunca hardcodees credenciales.
Ejemplo 7: Monitoreo de Cambios
Caso de uso: Detectar cambios en una página web y enviar alerta.
Workflow:
1. Trigger (Schedule cada hora)
2. Playwright Node (goto):
- Action: goto
- URL: https://example.com/monitor
3. Playwright Node (getContent):
- Action: getText
- Selector: .content
4. Code Node (compare):
- Comparar con valor anterior (guardado en DB)
5. IF Node:
- Si hay cambios → Continuar
- Si no hay cambios → Fin
6. Database Node (update):
- Guardar nuevo valor
7. Telegram Node (alert):
- Enviar notificación de cambio
Nodo 4 – Code (compare):
const currentContent = $input.item.json.text;
const previousContent = $('Database').item.json.previous_content; // Del nodo Database anterior
if (currentContent !== previousContent) {
return {
changed: true,
previous: previousContent,
current: currentContent,
timestamp: new Date().toISOString()
};
} else {
return { changed: false };
}
Ejemplo 8: Extracción de Datos Dinámicos (SPA)
Caso de uso: Scraping de Single Page Application (React, Vue, etc.).
Workflow:
1. Trigger (Manual)
2. Playwright Node (goto):
- Action: goto
- URL: https://example.com/spa
3. Playwright Node (waitLoaded):
- Action: waitForSelector
- Selector: [data-loaded="true"]
4. Playwright Node (extractState):
- Action: evaluate
- Expression: (ver código)
5. Code Node (process):
- Procesar datos JSON
Nodo 4 – extractState (evaluate):
() => {
// Esperar a que la app cargue datos
return new Promise((resolve) => {
const checkLoaded = setInterval(() => {
if (window.__APP_STATE__) {
clearInterval(checkLoaded);
resolve(window.__APP_STATE__);
}
}, 100);
setTimeout(() => {
clearInterval(checkLoaded);
resolve(null);
}, 10000);
});
}
Ejemplo 9: Interacción con Dropdowns
Caso de uso: Seleccionar opción en dropdown y extraer resultados filtrados.
Workflow:
1. Trigger (Webhook)
2. Playwright Node (goto):
- Action: goto
- URL: https://example.com/filter
3. Playwright Node (selectCategory):
- Action: selectOption
- Selector: #category
- Value: {{ $json.category }}
4. Playwright Node (waitResults):
- Action: waitForSelector
- Selector: .results
5. Playwright Node (extractResults):
- Action: evaluate
- Expression: (ver código)
Nodo 5 – extractResults (evaluate):
() => {
const items = Array.from(document.querySelectorAll('.result-item'));
return items.map(item => ({
title: item.querySelector('.title')?.textContent.trim(),
price: item.querySelector('.price')?.textContent.trim(),
link: item.querySelector('a')?.href
}));
}
Ejemplo 10: Manejo de Múltiples Pestañas
Caso de uso: Abrir múltiples URLs en paralelo y capturar screenshots.
Workflow:
1. Trigger (Manual con array de URLs)
2. Split In Batches Node:
- Batch Size: 1
3. Playwright Node (goto):
- Action: goto
- URL: {{ $json.url }}
4. Playwright Node (screenshot):
- Action: screenshot
- Full Page: true
5. Merge Node:
- Combinar resultados
6. Output: Array de screenshots
Nota: Playwright en n8n maneja una pestaña a la vez por workflow. Para paralelismo real, necesitarías múltiples workflows o Browserless.
Ejemplo 11: Scraping de E-commerce (Precios)
Caso de uso: Monitorear precios de productos en tienda online.
Workflow:
1. Trigger (Schedule cada 6 horas)
2. Playwright Node (goto):
- Action: goto
- URL: https://store.example.com/product/123
3. Playwright Node (waitProduct):
- Action: waitForSelector
- Selector: .product-price
4. Playwright Node (extractPrice):
- Action: evaluate
- Expression: (ver código)
5. Code Node (compare):
- Comparar con precio anterior
6. IF Node:
- Si precio bajó → Alerta
7. Database Node:
- Guardar precio actual
8. Telegram Node:
- Notificar si hay cambio
Nodo 4 – extractPrice (evaluate):
() => {
const priceText = document.querySelector('.product-price')?.textContent;
const price = parseFloat(priceText?.replace(/[^0-9.,]/g, '').replace(',', '.'));
const title = document.querySelector('h1.product-title')?.textContent.trim();
const availability = document.querySelector('.stock-status')?.textContent.trim();
return {
title,
price,
availability,
timestamp: new Date().toISOString()
};
}
Ejemplo 12: Automatización de Testing Básico
Caso de uso: Validar que elementos clave de una página funcionan correctamente.
Workflow:
1. Trigger (Schedule diario)
2. Playwright Node (goto):
- Action: goto
- URL: https://example.com
3. Playwright Node (checkTitle):
- Action: getText
- Selector: h1
4. Code Node (validate):
- Validar que título existe
5. Playwright Node (checkLinks):
- Action: evaluate
- Expression: (ver código)
6. Code Node (validateLinks):
- Validar que links funcionan
7. IF Node:
- Si hay errores → Alerta
Nodo 5 – checkLinks (evaluate):
() => {
const links = Array.from(document.querySelectorAll('a[href]'));
return links.map(link => ({
text: link.textContent.trim(),
href: link.href,
isExternal: !link.href.startsWith(window.location.origin)
}));
}
—
Mejores Prácticas
Gestión de Recursos
✅ DO:
- Cerrar páginas cuando no se necesiten (Playwright lo hace automáticamente)
- Limitar número de instancias simultáneas (máx. 5-10 por servidor)
- Usar headless mode para producción (menor consumo)
- Configurar timeouts apropiados (no demasiado largos)
❌ DON’T:
- Abrir múltiples navegadores simultáneos sin control
- Dejar workflows ejecutándose indefinidamente
- Usar timeouts muy largos (bloquean recursos)
Selectores Efectivos
✅ DO:
- Preferir IDs sobre clases:
#usernamevs.input-field - Usar selectores específicos:
button[type="submit"]vsbutton - Usar data attributes cuando sea posible:
[data-testid="submit"] - Combinar selectores para precisión:
form.login-form input#email
❌ DON’T:
- Usar selectores que dependan de posición:
:nth-child(3) - Selectores genéricos:
div,span - Selectores que cambian dinámicamente:
.class-123456
Ejemplos de buenos selectores:
/* ✅ Bueno */
#login-button
form[action="/login"] button
[data-testid="submit-form"]
/* ❌ Malo */
div > div > button
.button:nth-child(2)
.class-abc123
Manejo de Errores
✅ DO:
- Añadir nodos de error handling en workflows críticos
- Implementar retry logic para operaciones críticas
- Logging de errores para debugging
- Validar datos antes de procesar
Ejemplo de retry con Code Node:
const maxRetries = 3;
let attempt = 0;
while (attempt < maxRetries) {
try {
// Tu lógica aquí
return { success: true, data: result };
} catch (error) {
attempt++;
if (attempt >= maxRetries) {
return { success: false, error: error.message };
}
// Esperar antes de reintentar
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
}
}
Seguridad
✅ DO:
- Usar variables de entorno para credenciales:
{{ $env.USERNAME }} - Validar URLs antes de navegar
- Limitar acceso a recursos sensibles
- Usar HTTPS siempre que sea posible
❌ DON’T:
- Hardcodear credenciales en workflows
- Navegar a URLs no validadas
- Exponer tokens/API keys en logs
Ejemplo seguro:
{
"action": "fill",
"selector": "#password",
"text": "{{ $env.SECURE_PASSWORD }}"
}
Performance
✅ Optimizaciones:
- Usar
domcontentloadeden vez denetworkidlecuando sea posible - Combinar operaciones en un solo
evaluatecuando sea posible - Evitar esperas innecesarias
- Usar selectores específicos (más rápidos)
Ejemplo optimizado:
// ❌ Lento: Múltiples operaciones
await page.goto(url);
await page.waitForSelector('.content');
const title = await page.textContent('h1');
const content = await page.textContent('p');
// ✅ Rápido: Una sola operación
await page.goto(url);
const data = await page.evaluate(() => ({
title: document.querySelector('h1')?.textContent,
content: document.querySelector('p')?.textContent
}));
—
Troubleshooting Común

Error: «Playwright browser not found»
Síntomas:
Error: Executable doesn't exist at /path/to/chromium
Causa: Navegadores de Playwright no instalados.
Solución:
# En el servidor donde corre n8n
npx playwright install chromium
# O instalar todos los navegadores
npx playwright install
Verificación:
npx playwright --version
Error: «Timeout waiting for selector»
Síntomas:
Error: Timeout 30000ms exceeded while waiting for selector ".content"
Causa: Elemento no aparece en tiempo esperado.
Soluciones:
- Aumentar timeout:
{
"action": "waitForSelector",
"selector": ".content",
"timeout": 60000
}
- Verificar selector:
– Usa DevTools del navegador para verificar que el selector existe
– Prueba el selector en consola: document.querySelector('.content')
- Añadir waitForSelector antes de interactuar:
{
"action": "waitForSelector",
"selector": ".content",
"state": "visible"
}
- Usar waitForLoadState:
{
"action": "waitForLoadState",
"state": "networkidle"
}
Error: «Page crashed» o «Browser closed unexpectedly»
Síntomas:
Error: Page crashed
Error: Browser closed unexpectedly
Causa: Falta de recursos (RAM/CPU).
Soluciones:
- Aumentar recursos del servidor:
– Mínimo 4GB RAM libres
– 2+ CPU cores
- Reducir número de instancias simultáneas:
– Limitar workflows que usan Playwright
– No ejecutar más de 5-10 simultáneos
- Considerar usar Browserless:
– Para aislar recursos del navegador
– Mejor gestión de memoria
- Verificar recursos:
# Ver RAM libre
free -h
# Ver CPU
top
Error: «Element not found»
Síntomas:
Error: Element not found: selector "#button"
Causa: Selector incorrecto o elemento no visible.
Soluciones:
- Verificar selector con DevTools:
– Abre la página en navegador
– Usa DevTools para probar selector
– Verifica que el elemento existe
- Añadir waitForSelector:
{
"action": "waitForSelector",
"selector": "#button",
"state": "visible"
}
- Usar selectores más específicos:
/* En vez de */
button
/* Usa */
form.login-form button[type="submit"]
- Verificar que elemento no esté en iframe:
– Si está en iframe, necesitas cambiar contexto primero
Performance: Workflow muy lento
Síntomas:
- Workflow tarda más de 30 segundos
- Múltiples timeouts
Causas y Soluciones:
- Múltiples navegaciones innecesarias:
– Solución: Combinar operaciones cuando sea posible
– Usar evaluate para múltiples extracciones
- Esperas demasiado largas:
– Solución: Usar domcontentloaded en vez de networkidle
{
"action": "goto",
"url": "https://example.com",
"waitUntil": "domcontentloaded"
}
- Selectores ineficientes:
– Solución: Usar selectores específicos (IDs, data attributes)
- Demasiadas operaciones secuenciales:
– Solución: Combinar en evaluate cuando sea posible
Ejemplo de optimización:
// ❌ Lento: 5 operaciones
const title = await page.textContent('h1');
const price = await page.textContent('.price');
const description = await page.textContent('.description');
const image = await page.getAttribute('img', 'src');
const link = await page.getAttribute('a', 'href');
// ✅ Rápido: 1 operación
const data = await page.evaluate(() => ({
title: document.querySelector('h1')?.textContent,
price: document.querySelector('.price')?.textContent,
description: document.querySelector('.description')?.textContent,
image: document.querySelector('img')?.src,
link: document.querySelector('a')?.href
}));
Error: «Navigation timeout»
Síntomas:
Error: Navigation timeout of 30000 ms exceeded
Causa: Página tarda demasiado en cargar.
Soluciones:
- Aumentar timeout:
{
"action": "goto",
"url": "https://example.com",
"timeout": 60000
}
- Usar waitUntil diferente:
{
"action": "goto",
"url": "https://example.com",
"waitUntil": "domcontentloaded"
}
- Verificar que la URL sea accesible:
curl -I https://example.com
—
Integración con Otros Nodos
El nodo Playwright se integra perfectamente con otros nodos de n8n. Aquí están los flujos más comunes:
Playwright → Code Node
Uso: Procesar datos extraídos, transformar formato, validar datos.
Ejemplo:
1. Playwright Node (getText):
- Extraer texto
2. Code Node (process):
- Limpiar y formatear texto
- Validar formato
- Extraer información específica
3. Output: Datos procesados
Code Node:
const rawText = $input.item.json.text;
// Limpiar y procesar
const cleaned = rawText
.trim()
.replace(/\s+/g, ' ')
.split('\n')
.filter(line => line.length > 0);
// Extraer información
const email = cleaned.find(line => line.includes('@'));
const phone = cleaned.find(line => /\+?\d{9,}/.test(line));
return {
cleaned,
email,
phone,
lineCount: cleaned.length
};
Playwright → HTTP Request
Uso: Enviar datos a API, subir screenshots/PDFs, notificar resultados.
Ejemplo:
1. Playwright Node (screenshot):
- Capturar pantalla
2. HTTP Request Node (upload):
- Subir a S3/Google Drive
- Método: POST
- Body: Imagen en base64
3. Output: URL de imagen subida
HTTP Request Node:
{
"method": "POST",
"url": "https://api.example.com/upload",
"headers": {
"Authorization": "Bearer {{ $env.API_TOKEN }}",
"Content-Type": "application/json"
},
"body": {
"image": "{{ $json.screenshot }}",
"filename": "screenshot.png"
}
}
Playwright → Database
Uso: Guardar datos scrapeados, registrar ejecuciones, almacenar métricas.
Ejemplo:
1. Playwright Node (extractData):
- Extraer datos de página
2. Database Node (PostgreSQL):
- Operación: Insert
- Tabla: scraped_data
- Campos: title, content, url, scraped_at
3. Output: ID del registro insertado
Database Node (PostgreSQL):
INSERT INTO scraped_data (title, content, url, scraped_at)
VALUES ($1, $2, $3, $4)
RETURNING id;
Parámetros:
$1:{{ $json.title }}$2:{{ $json.content }}$3:{{ $json.url }}$4:{{ $now }}
Playwright → Telegram/Email
Uso: Notificar errores, enviar reportes, alertar cambios.
Ejemplo:
1. Playwright Node (monitor):
- Detectar cambios
2. IF Node:
- Si hay cambios → Continuar
3. Telegram Node:
- Enviar notificación con detalles
Telegram Node:
{
"chatId": "{{ $env.TELEGRAM_CHAT_ID }}",
"text": "🔔 Cambio detectado en {{ $json.url }}\n\n{{ $json.details }}",
"parseMode": "Markdown"
}
Flujo Completo: Scraping → Procesamiento → Almacenamiento → Notificación
Ejemplo real:
1. Schedule Trigger (cada hora)
2. Playwright Node (goto):
- Navegar a página
3. Playwright Node (extract):
- Extraer datos
4. Code Node (process):
- Procesar y validar
5. Database Node (save):
- Guardar en PostgreSQL
6. IF Node (checkChanges):
- Comparar con anterior
7. Telegram Node (notify):
- Notificar si hay cambios
—
Casos de Uso Avanzados
Scraping de E-commerce
Objetivo: Monitorear precios, disponibilidad y reviews de productos.
Workflow típico:
1. Schedule (cada 6 horas)
2. Playwright (goto producto)
3. Playwright (extract: precio, título, disponibilidad)
4. Database (comparar con precio anterior)
5. IF (precio bajó >10%)
6. Telegram (notificar oferta)
Consideraciones:
- Respetar
robots.txty términos de servicio - Usar delays entre requests (no hacer scraping agresivo)
- Rotar User-Agents si es necesario
- Manejar páginas dinámicas (SPA) con
waitForSelector
Automatización de Testing
Objetivo: Validar que elementos clave de una página funcionan.
Workflow típico:
1. Schedule (diario)
2. Playwright (goto página)
3. Playwright (validar: título, links, formularios)
4. Code (evaluar resultados)
5. IF (hay errores)
6. Email (reporte de errores)
Validaciones comunes:
- Títulos y meta tags
- Links funcionando (no 404)
- Formularios submittables
- Elementos visibles
- Performance (tiempo de carga)
Generación de Reportes
Objetivo: Crear reportes automáticos con screenshots y PDFs.
Workflow típico:
1. Schedule (semanal)
2. Playwright (goto dashboard)
3. Playwright (screenshot)
4. Playwright (pdf)
5. Code (combinar datos)
6. Email (enviar reporte)
Mejoras:
- Combinar múltiples screenshots
- Añadir métricas y gráficos
- Formatear PDF profesionalmente
- Enviar a múltiples destinatarios
Monitoreo y Alertas
Objetivo: Detectar cambios en sitios web y alertar.
Workflow típico:
1. Schedule (cada hora)
2. Playwright (goto página)
3. Playwright (extract contenido)
4. Database (comparar con anterior)
5. IF (hay cambios)
6. Telegram/Slack (alerta)
Tipos de monitoreo:
- Cambios en contenido
- Nuevos productos/publicaciones
- Cambios de precio
- Disponibilidad de stock
- Estado de servicios (up/down)
Preguntas Frecuentes
¿El nodo Playwright nativo requiere instalación adicional?
No, el nodo Playwright está incluido en n8n desde la versión 1.0+. Solo necesitas tener n8n instalado. La primera vez que uses el nodo, n8n intentará instalar los navegadores Playwright automáticamente.
¿Puedo usar el nodo Playwright con Docker?
Sí, pero necesitas asegurarte de que los navegadores Playwright estén instalados dentro del contenedor. Añade esto a tu Dockerfile:
RUN npx playwright install chromium
RUN npx playwright install-deps chromium
¿Cuánta RAM consume el nodo Playwright?
Cada instancia del navegador consume aproximadamente 200-400MB de RAM. Para workflows simples, esto es manejable. Si necesitas múltiples instancias simultáneas, considera usar Browserless para mejor gestión de recursos.
¿Puedo usar el nodo Playwright para scraping masivo?
Técnicamente sí, pero no es la mejor opción. El nodo nativo está limitado por los recursos de tu servidor n8n. Para scraping masivo (>100 páginas/hora), Browserless es más adecuado por su capacidad de pooling y escalabilidad.
¿Cómo manejo páginas con JavaScript dinámico?
Usa waitForSelector o waitForLoadState para esperar a que el contenido se cargue:
{
"action": "waitForSelector",
"selector": "[data-loaded='true']",
"state": "visible"
}
O usa waitForLoadState con networkidle:
{
"action": "waitForLoadState",
"state": "networkidle"
}
¿Puedo hacer scraping de sitios que requieren login?
Sí, el nodo Playwright puede manejar login. Usa fill para credenciales, click para submit, y waitForNavigation para esperar el redirect. Importante: Usa variables de entorno para credenciales, nunca las hardcodees.
¿El nodo Playwright funciona con sitios que usan CAPTCHA?
No directamente. Los CAPTCHAs están diseñados para prevenir automatización. Para sitios con CAPTCHA, necesitarías servicios especializados (2Captcha, Anti-Captcha) o reconsiderar si el scraping es apropiado.
¿Cómo extraigo datos de una tabla HTML?
Usa la acción evaluate con JavaScript:
() => {
const rows = Array.from(document.querySelectorAll('table tr'));
return rows.map(row => {
const cells = Array.from(row.querySelectorAll('td, th'));
return cells.map(cell => cell.textContent.trim());
});
}
¿Puedo capturar screenshots de páginas completas (full page)?
Sí, usa la acción screenshot con fullPage: true:
{
"action": "screenshot",
"fullPage": true,
"type": "png"
}
¿Cómo genero un PDF de una página web?
Usa la acción pdf:
{
"action": "pdf",
"format": "A4",
"printBackground": true
}
¿El nodo Playwright es más lento que Browserless?
Depende. Para una sola instancia, el nodo nativo puede ser más rápido (sin latencia de red). Para múltiples instancias simultáneas, Browserless con pooling es más eficiente.
¿Puedo usar el nodo Playwright en n8n Cloud?
Sí, el nodo Playwright funciona en n8n Cloud, pero ten en cuenta las limitaciones de recursos. Para uso intensivo, self-hosted es más adecuado.
¿Cómo manejo errores de timeout?
Aumenta el timeout en la configuración del nodo:
{
"action": "waitForSelector",
"selector": ".content",
"timeout": 60000
}
O usa waitUntil diferente:
{
"action": "goto",
"url": "https://example.com",
"waitUntil": "domcontentloaded"
}
¿Puedo ejecutar JavaScript personalizado en la página?
Sí, usa la acción evaluate:
{
"action": "evaluate",
"expression": "() => document.title"
}
¿Cómo extraigo datos de múltiples páginas?
Usa un loop con Split In Batches o HTTP Request para obtener URLs, luego Playwright para cada URL:
1. HTTP Request (obtener lista de URLs)
2. Split In Batches (dividir URLs)
3. Playwright (scraping de cada URL)
4. Merge (combinar resultados)
—
Conclusión
El nodo Playwright nativo de n8n es una herramienta poderosa y simple para automatizar tareas web sin la complejidad de servicios externos como Browserless. Es perfecto para casos de uso de bajo a medio volumen donde la simplicidad y la integración directa con n8n son prioridades.
Resumen de puntos clave:
- ✅ Simplicidad: Sin Docker, sin configuración compleja, funciona out-of-the-box
- ✅ Integración perfecta: Funciona sin problemas con otros nodos de n8n
- ✅ Casos de uso ideales: Scraping ocasional, automatización de formularios, capturas de pantalla, generación de PDFs
- ✅ Limitaciones: Escalabilidad limitada, consume recursos del servidor n8n
- ✅ Alternativa: Para alto volumen, Browserless es más adecuado
Próximos pasos:
- Prueba los ejemplos: Empieza con el ejemplo 1 (scraping básico) y ve avanzando
- Descarga los workflows: Todos los ejemplos están disponibles en [GitHub](https://github.com/ziruelen/learningaiagents/tree/main/n8n/n8n-playwright-nodo-nativo)
- Explora más: Revisa la [documentación oficial de n8n](https://docs.n8n.io/) y [Playwright](https://playwright.dev/)
- Únete a la comunidad: [Foros de n8n](https://community.n8n.io/) para preguntas y ejemplos
¿Quieres automatizar más? Descubre [20 Workflows de n8n que Dominan los Expertos](https://www.eldiarioia.es/2025/XX/XX/nodos-n8n-expandido/) o aprende [integración con bases de datos](https://www.eldiarioia.es/2025/11/06/n8n-database-workflows-postgresql-mysql-mongodb/).
—Enlaces Relacionados
- [Guía Completa de n8n v2](https://www.eldiarioia.es/2025/XX/XX/guia-n8n-v2/) – Referencia fundamental
- [n8n Database Workflows](https://www.eldiarioia.es/2025/11/06/n8n-database-workflows-postgresql-mysql-mongodb/) – Integración con bases de datos
- [Browserless + Playwright](https://www.eldiarioia.es/2025/XX/XX/browserless-playwright/) – Cuándo usar Browserless
- [Automatización con n8n: 20 Workflows](https://www.eldiarioia.es/2025/XX/XX/nodos-n8n-expandido/) – Más ejemplos
- [Domina el Nodo HTTP Request](https://www.eldiarioia.es/2025/XX/XX/http-request-n8n/) – Complemento para APIs
- [Bot de Telegram con n8n](https://www.eldiarioia.es/2025/10/09/telegram-bot-n8n-gratis/) – Notificaciones
- [Home Assistant + n8n](https://www.eldiarioia.es/2025/XX/XX/home-assistant-n8n/) – Automatización avanzada
📦 Descargar Ejemplos
Todos los workflows de ejemplo están disponibles en GitHub:
🔗 [Ver ejemplos en GitHub](https://github.com/ziruelen/learningaiagents/tree/main/n8n/n8n-playwright-nodo-nativo)
Incluye:
- ✅ 7 workflows JSON listos para importar
- ✅ Guía de selectores comunes
- ✅ Ejemplos de código comentados
- ✅ README con instrucciones detalladas
¿Tienes preguntas o problemas? Únete a la [comunidad de n8n](https://community.n8n.io/) o deja un comentario abajo.
