Una plataforma de código bajo que combina la simplicidad sin código con el poder del código completo 🚀
Empieza ahora gratis
Condiciones de espera personalizadas con waitForFunction en Puppeteer
Marzo 21, 2025
9
min leer

Condiciones de espera personalizadas con waitForFunction en Puppeteer

George Miloradovich
Investigador, redactor y entrevistador de casos prácticos
Tabla de contenidos.

Quiero tu Titiritero ¿Scripts para gestionar mejor sitios web dinámicos? Aquí está la clave: waitForFunction le permite definir reglas de espera personalizadas para garantizar que su automatización funcione sin problemas con el contenido cambiante.

Por qué usar waitForFunction?

  • Controlar el tiempo:Esperar hasta que se cumplan condiciones específicas (por ejemplo, carga de elementos, cambios de texto).
  • Manejar contenido dinámico:Perfecto para sitios web modernos y dinámicos.
  • Evite errores:Evite retrasos innecesarios o interacciones prematuras.

Cómo funciona:

  • Escribe condiciones de JavaScript que retornen true cuando esté listo.
  • Utilice opciones como frecuencia de sondeo (raf, mutation, o milisegundos) y tiempos de espera para un mejor rendimiento.
  • Combine comprobaciones DOM con respuestas API para escenarios avanzados.

Ejemplo:

await page.waitForFunction(
  () => document.querySelector('.status').textContent === 'Ready'
);

Características Clave:

  • Supervisar la visibilidad de los elementos, el contenido del texto o las propiedades personalizadas.
  • Combine múltiples condiciones para flujos de trabajo complejos.
  • Maneje los tiempos de espera y los errores con elegancia.

Consejo: Utiliza waitForFunction para reemplazar obsoleto sleep llamadas y mejorar la eficiencia.

Descripción rápida:

Feature Que hace
Modos de sondeo Comprueba las condiciones a través de 'raf', 'mutation', o intervalos personalizados
Condiciones personalizadas Esperar estados DOM específicos o respuestas de API
Gestión del tiempo de espera Establecer tiempos de espera globales o específicos de la operación

Este método garantiza que sus scripts sean confiables, eficientes y estén listos para cualquier desafío de contenido dinámico.

Cómo esperar/dormir durante N segundos en titiritero?

titiritero

Conceptos básicos de waitForFunction

El waitForFunction El método de Puppeteer permite configurar condiciones personalizadas para que los scripts esperen antes de continuar. Aquí te explicamos cómo usarlo eficazmente.

Cómo escribir funciones de espera básicas

Aquí hay una forma sencilla de crear una función de espera:

// Wait until the input element has a specific value
await page.waitForFunction(
  'document.getElementById("loginUsername").value === "hello"'
);

// Using an arrow function for a condition
await page.waitForFunction(
  () => document.querySelector('.status').textContent === 'Ready'
);

La clave aquí es que su función debe devolver un valor de verdad antes de que el guión pueda avanzar.

Ahora veamos cómo configurarlo para un mejor rendimiento.

Configuración de parámetros de función

Puedes afinar waitForFunction Pasando un objeto de opciones. Los parámetros clave incluyen:

Parámetro Descripción original Valores comunes
polling Con qué frecuencia se verifica la condición 'raf', 'mutación' o milisegundos
tiempo de espera Tiempo máximo de espera Predeterminado: 30,000 30 ms (XNUMX segundos)

Modos de sondeo:

  1. RequestAnimationFrame ('raf')
    Ideal para monitorear cambios de estilo, ya que verifica las condiciones durante cada cuadro de animación.
  2. Observador de mutaciones ('mutación')
    Útil para rastrear cambios en la estructura del DOM. Activa comprobaciones cada vez que el DOM se actualiza.
  3. Intervalo personalizado (milisegundos)
    Por ejemplo, esto comprueba la condición cada segundo:
    await page.waitForFunction(
      () => document.readyState === 'complete',
      { polling: 1000, timeout: 5000 }
    );
    

Elija el modo de votación según sus necesidades:

  • Use 'raf' para animaciones o actualizaciones de estilo.
  • Optar por 'mutation' para cambios relacionados con DOM.
  • Establezca un intervalo personalizado (milisegundos) para casos de uso más amplios.

Creación de reglas de espera personalizadas

Comprobación del estado de visualización del elemento

Para confirmar que un elemento es visible, puedes comprobar su presencia y dimensiones:

await page.waitForFunction(() => {
    const element = document.querySelector('.tv-lightweight-charts');
    return element && element.offsetHeight > 0 && element.offsetWidth > 0;
});

Esto garantiza que el elemento exista y tenga dimensiones visibles en la página. Es especialmente útil para contenido dinámico que tarda tiempo en cargarse correctamente.

Prueba de propiedades de texto y elementos

Además de los controles visuales, puedes supervisar el contenido del texto o propiedades específicas de los elementos:

// Wait for specific text content
await page.waitForFunction(
    selector => {
        const element = document.querySelector(selector);
        return element && element.textContent.includes('Ready');
    },
    {},
    '.status-message'
);

Para realizar comprobaciones de propiedad más detalladas, pase argumentos adicionales:

const expectedValue = 'completed';
const selector = '.status';

await page.waitForFunction(
    (sel, val) => {
        const element = document.querySelector(sel);
        return element && element.getAttribute('data-state') === val;
    },
    {},
    selector,
    expectedValue
);

Combinación de múltiples reglas de espera

Una vez que haya probado las condiciones individuales, puede combinarlas para crear escenarios más complejos. Por ejemplo:

await page.waitForFunction(() => {
    // Check multiple elements and conditions
    const button = document.querySelector('.donate-button');
    const searchBox = document.querySelector('.search-button');

    return button && 
           searchBox && 
           button.offsetHeight > 0 && 
           searchBox.offsetHeight > 0 &&
           !button.disabled;
});

Para manejar múltiples elementos con condiciones independientes, utilice Promise combinaciones:

Patrón de espera Caso de uso Implementación
Todos los elementos Espere a que se completen varios elementos requeridos Promise.all()
Cualquier elemento Continuar cuando aparezca el primer elemento Promise.race()
Lógica personalizada Manejar comprobaciones condicionales complejas Funciones de espera combinadas

Para operaciones asincrónicas, puede crear condiciones de espera avanzadas:

await page.waitForFunction(
    async () => {
        const response = await fetch('/api/status');
        const data = await response.json();
        return data.isReady && document.querySelector('.content').offsetHeight > 0;
    },
    { polling: 'mutation' }
);

Este método combina Validación de respuesta de API con Comprobaciones de elementos DOM, garantizando que tanto los datos como el contenido visual estén listos.

sbb-itb-23997f1

Métodos avanzados de waitForFunction

Escritura de condiciones complejas en JavaScript

Para aplicaciones web más dinámicas, puede utilizar esperarFunción Para crear condiciones detalladas de JavaScript. Aquí tienes un ejemplo:

await page.waitForFunction(
    (threshold) => {
        const chart = document.querySelector('.tv-lightweight-charts');
        const dataPoints = chart?.querySelectorAll('.data-point');

        return chart && 
               dataPoints?.length > threshold && 
               Array.from(dataPoints).every(point => 
                   point.getBoundingClientRect().height > 0 &&
                   !point.classList.contains('loading')
               );
    },
    { polling: 'mutation' },
    5
);

Este script asegura:

  • El contenedor del gráfico existe.
  • Hay un número mínimo de puntos de datos.
  • Todos los puntos de datos son visibles.
  • Ninguno de los puntos está en estado de carga.

También puedes combinar comprobaciones asincrónicas con evaluaciones DOM para escenarios más complejos:

await page.waitForFunction(
    async () => {
        // Check if the container is ready
        const container = document.querySelector('.dynamic-content');
        if (!container || container.offsetHeight === 0) return false;

        // Validate API response
        try {
            const response = await fetch('/api/status');
            const data = await response.json();
            return data.isReady && container.children.length > 0;
        } catch {
            return false;
        }
    },
    { 
        polling: 'raf',
        timeout: 30000
    }
);

Este enfoque combina comprobaciones DOM con una llamada API para garantizar que tanto la interfaz de usuario como el backend estén sincronizados.

Manejo de tiempos de espera y errores

La gestión del tiempo de espera es crucial cuando se trabaja con esperarFunciónA continuación, se muestra un ejemplo de cómo gestionar los tiempos de espera de forma eficaz:

try {
    await page.setDefaultTimeout(60000); // Set a global timeout of 60 seconds

    await page.waitForFunction(
        () => {
            const element = document.querySelector('.dynamic-element');
            return element?.complete === true;
        },
        {
            timeout: 45000, // Specific timeout for this operation
            polling: 'mutation'
        }
    );
} catch (error) {
    if (error.name === 'TimeoutError') {
        console.error('Element state check timed out:', error.message);
        await page.reload(); // Reload page as a fallback
    }
    throw error;
}

A continuación se presenta una descripción general rápida de las estrategias de tiempo de espera:

Estrategia de tiempo de espera Caso de uso Configuration
Tiempo de espera predeterminado Operaciones generales page.setDefaultTimeout()
Tiempo de espera de navegación Carga de página page.setDefaultNavigationTimeout()
Específico de la operación Comprobaciones detalladas Ingrese al timeout opción en el método
Espera infinita Retrasos conocidos timeout: 0

Para mejorar el manejo de errores:

  • Ajuste la configuración de tiempo de espera según la complejidad de cada operación.
  • Use try-catch bloques para recuperarse con gracia de los errores.
  • Supervisar la actividad de la red para identificar cuellos de botella.
  • Implementar acciones de respaldo, como recargar la página, cuando se producen tiempos de espera.
  • Verifique dos veces los selectores para evitar retrasos innecesarios.

Estas prácticas ayudarán a garantizar que sus scripts sean confiables y eficientes.

Hacer que waitForFunction se ejecute más rápido

Consejos sobre velocidad y recursos

Para obtener esperarFunción Para una mayor eficiencia, concéntrese en estrategias de espera inteligentes y una gestión adecuada de los recursos. Utilice las herramientas de desarrollo del navegador para medir los tiempos de carga y establecer tiempos de espera precisos.

// Optimize waiting with a networkidle strategy
await page.goto('https://example.com', {
    waitUntil: 'networkidle2',
    timeout: 30000
});

// Combine checks in a single evaluate call
await page.evaluate(() => {
    const element = document.querySelector('.dynamic-content');
    const isVisible = element?.offsetHeight > 0;
    const hasData = element?.children.length > 0;
    return isVisible && hasData;
});

Para reducir el uso de recursos:

  • Bloquea activos innecesarios como imágenes o fuentes.
  • Use waitForSelector or waitForFunction En lugar de obsoleto waitForTimeout.
  • Combine varios cheques en uno solo evaluate Llamada para reducir la comunicación entre el navegador y el nodo.
Estrategia Impacto en el rendimiento Mejor caso de uso
networkidle2 Moderado Navegación de página
waitForSelector Rápido Comprobaciones de elementos individuales
waitForFunction Variable Condiciones complejas
Conjunto evaluate Empresarial Comprobaciones de elementos múltiples

Estos métodos pueden ayudar a abordar cuellos de botella comunes, que se tratan en la siguiente sección.

Solucionar problemas comunes

Los problemas de rendimiento suelen deberse a patrones de espera ineficientes. A continuación, se explica cómo solucionarlos:

Problemas con el selector
Los selectores demasiado rígidos pueden provocar fallos. Simplifíquelos para una mayor fiabilidad:

// Avoid rigid selectors like this
await page.waitForSelector('div.container > div:nth-child(2) > span.text-red');

// Use a more flexible approach
await page.waitForFunction(
    () => document.querySelector('.text-red')?.offsetParent !== null
);

Gestión de Recursos
Gestione los recursos y evite retrasos innecesarios:

try {
    await page.waitForFunction(
        () => document.readyState === 'complete' &&
              performance.now() > 1000
    );
} catch (error) {
    console.error('Page load timeout:', error.message);
}

"Puppeteer tiene una arquitectura basada en eventos, lo que elimina muchas posibles fallas. No hay necesidad de maldad. sleep[undefined] llamadas en los guiones de titiritero." - Léame de Puppeteer

Envuelva siempre los métodos de espera en try...catch Bloques para gestionar errores con elegancia y ofrecer opciones de respaldo. Este enfoque garantiza la robustez y fiabilidad de sus scripts.

Usos comunes de las reglas de espera personalizadas

Carga de productos de la tienda en línea

Asegurarse de que los productos se carguen correctamente es fundamental para recopilar datos precisos. Utilice una regla de espera personalizada para pausar la ejecución hasta que los productos se hayan cargado por completo:

await page.waitForFunction(() => {
    const products = document.querySelectorAll('.product-card');
    return products.length > 0 && all images and prices fully load;
});

Para mayor precisión, puede utilizar este enfoque:

await page.waitForFunction(() => {
    const productDetails = document.querySelector('.product-details');
    return productDetails && 
           productDetails.offsetHeight > 0 && 
           productDetails.querySelector('.inventory-status') !== null;
}, {timeout: 30000});

Esto garantiza que su script espere a que se carguen todos los elementos necesarios, mejorando la confiabilidad de la recopilación de datos en escenarios de comercio electrónico.

Carga de contenido en aplicaciones web modernas

Las aplicaciones web dinámicas suelen requerir condiciones de espera específicas para gestionar la carga de contenido. Por ejemplo, puedes esperar a que un elemento específico sea completamente visible:

await page.waitForFunction(() => {
    const element = document.querySelector('.tv-lightweight-charts');
    return element && element.offsetHeight > 0 && element.offsetWidth > 0;
});

Si es necesario cargar varias secciones, combine condiciones de la siguiente manera:

await page.waitForFunction(() => {
    const contentLoaded = document.querySelector('.content').children.length > 0;
    const dataUpdated = document.body.textContent.includes('Last updated:');
    return contentLoaded && dataUpdated;
}, {polling: 1000});

Este método ayuda a garantizar que sus scripts de automatización interactúen sin problemas con el contenido dinámico.

Detección de mensajes de error de formulario

La detección de errores de formulario utiliza una lógica similar a la de las comprobaciones de visibilidad de elementos. Así es como puedes supervisar los mensajes de error:

await page.waitForFunction(() => {
    const errorContainer = document.querySelector('.error-messages');
    const hasErrors = errorContainer?.children.length > 0;
    const isVisible = errorContainer?.offsetParent !== null;
    return hasErrors && isVisible;
});

También puede realizar un seguimiento de varios estados de validación de formulario utilizando condiciones de espera específicas:

Tipo de validación Condición de espera Caso de uso
Errores de campo Comprobar la presencia de una clase de error Validación de campos individuales
Errores en todo el formulario Monitorizar el contenedor de errores Estado general del formulario
Mensajes de éxito Esté atento a las pantallas de confirmación Finalización del envío
Estados de carga Estado del botón de envío de seguimiento Indicación de procesamiento

Conclusión

Puntos clave

El waitForFunction El método en Puppeteer evalúa las condiciones de JavaScript hasta que regresan true, ofreciendo un control preciso sobre las interacciones dinámicas de la página.

Éstos son algunos de los beneficios clave de usar waitForFunction:

  • Evaluación flexible:Maneja funciones asincrónicas para monitorear estados de páginas complejos.
  • Integración de contexto: Permite pasar directamente argumentos de Node.js al contexto del navegador.
  • Lógica personalizada:Permite una automatización personalizada en función de las condiciones específicas de la página.

Este enfoque es especialmente útil cuando los métodos de espera estándar no son suficientes. Por ejemplo, en aplicaciones avanzadas de una sola página, es posible que se carguen varios elementos simultáneamente o que sea necesario confirmar estados específicos de JavaScript antes de continuar.

Titiritero y Nodo tardío en acción

Nodo tardío

Latenode aprovecha waitForFunction Para mejorar la automatización del flujo de trabajo. Al integrar este método, Latenode ha creado un nodo de monitorización personalizado que verifica el estado del sitio web y realiza capturas de pantalla cuando no se cumplen ciertas condiciones.

Aquí hay un ejemplo de cómo Latenode utiliza waitForFunction Para garantizar que los elementos críticos se representen completamente antes de continuar:

await page.waitForFunction(() => {
    const element = document.querySelector('.tv-lightweight-charts');
    return element && element.offsetHeight > 0 && element.offsetWidth > 0;
});

Este fragmento espera un elemento con la clase .tv-lightweight-charts no sólo aparecer en el DOM sino también representarse completamente.

Para obtener mejores resultados al usar Latenode con Puppeteer:

  • Establezca valores de tiempo de espera apropiados utilizando page.setDefaultTimeout().
  • Use try-catch bloques para un manejo robusto de errores.
  • Realice un seguimiento de los tiempos de ejecución para ajustar sus condiciones de espera.

Blog y artículos

Blogs relacionados

Caso de uso

Respaldado por