Quer que seus scripts do Puppeteer lidem melhor com sites dinâmicos? Aqui está o ponto-chave: waitForFunction permite definir regras de espera personalizadas para garantir que sua automação funcione perfeitamente com conteúdos que mudam.
Por que usar waitForFunction?
- Controle de tempo: Aguarde até que condições específicas sejam atendidas (por exemplo, elementos serem carregados ou textos mudarem).
- Lide com conteúdo dinâmico: Ideal para sites modernos e dinâmicos.
- Evite erros: Elimine atrasos desnecessários ou interações prematuras.
Como funciona:
- Escreva condições em JavaScript que retornem
truequando estiverem prontas. - Use opções como frequência de polling (
raf,mutationou milissegundos) e timeouts para melhorar o desempenho. - Combine verificações do DOM com respostas de API para fluxos avançados.
Exemplo:
await page.waitForFunction(
() => document.querySelector('.status').textContent === 'Ready'
);
Recursos principais:
- Monitore visibilidade de elementos, conteúdo de texto ou propriedades personalizadas.
- Combine várias condições para fluxos complexos.
- Lide com timeouts e erros de forma eficiente.
Dica: Use waitForFunction para substituir chamadas sleep obsoletas e melhorar a eficiência.
Visão geral rápida:
| Recurso | O que faz |
|---|---|
| Modos de polling | Verifica condições por meio de 'raf', 'mutation' ou intervalos personalizados |
| Condições personalizadas | Aguarda estados específicos do DOM ou respostas de API |
| Gerenciamento de timeout | Define timeouts específicos por operação ou globais |
Esse método garante que seus scripts sejam confiáveis, eficientes e estejam prontos para qualquer desafio de conteúdo dinâmico.
Como esperar / pausar por N segundos no puppeteer?
Conceitos básicos de waitForFunction
O método waitForFunction no Puppeteer permite configurar condições personalizadas que seus scripts devem aguardar antes de continuar. Veja como usá-lo de forma eficiente.
Como escrever funções básicas de espera
Veja uma forma simples de criar uma função 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'
);
O ponto principal é que sua função precisa retornar um valor truthy antes que o script possa avançar [1].
Agora, veja como configurá-lo para obter melhor desempenho.
Configurando parâmetros da função
Você pode ajustar waitForFunction passando um objeto de opções. Os principais parâmetros incluem:
| Parâmetro | Descrição | Valores comuns |
|---|---|---|
| polling | Com que frequência a condição é verificada | 'raf', 'mutation' ou milissegundos |
| timeout | Tempo máximo de espera | Padrão: 30.000 ms (30 segundos) |
Modos de polling [4]:
RequestAnimationFrame ('raf')
Ideal para monitorar mudanças de estilo, pois verifica condições em cada frame de animação.Mutation Observer ('mutation')
Útil para acompanhar mudanças na estrutura do DOM. Ele aciona verificações sempre que o DOM é atualizado.Intervalo personalizado (milissegundos)
Por exemplo, isto verifica a condição a cada segundo:await page.waitForFunction( () => document.readyState === 'complete', { polling: 1000, timeout: 5000 } );
Escolha o modo de polling com base nas suas necessidades:
- Use
'raf'para animações ou atualizações de estilo. - Escolha
'mutation'para alterações relacionadas ao DOM. - Defina um intervalo personalizado (milissegundos) para casos de uso mais amplos.
Criando regras de espera personalizadas
Verificando o status de exibição de elementos
Para confirmar se um elemento está visível, você pode verificar sua presença e dimensões:
await page.waitForFunction(() => {
const element = document.querySelector('.tv-lightweight-charts');
return element && element.offsetHeight > 0 && element.offsetWidth > 0;
});
Isso garante que o elemento exista e tenha dimensões visíveis na página. É especialmente útil para conteúdo dinâmico que leva tempo para carregar corretamente [2].
Testando texto e propriedades de elementos
Além das verificações visuais, você pode monitorar o conteúdo de texto ou propriedades específicas dos elementos:
// Wait for specific text content
await page.waitForFunction(
selector => {
const element = document.querySelector(selector);
return element && element.textContent.includes('Ready');
},
{},
'.status-message'
);
Para verificações de propriedades mais detalhadas, passe argumentos adicionais:
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
);
Combinando várias regras de espera
Depois de testar condições individuais, você pode combiná-las para fluxos mais complexos. Por exemplo:
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 lidar com vários elementos com condições independentes, use combinações de Promise [5]:
| Padrão de espera | Caso de uso | Implementação |
|---|---|---|
| Todos os elementos | Aguarda vários elementos necessários | Promise.all() |
| Qualquer elemento | Continua quando o primeiro elemento aparece | Promise.race() |
| Lógica personalizada | Lida com verificações condicionais complexas | Funções de espera combinadas |
Para operações assíncronas, você pode criar condições de espera avançadas:
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' }
);
Esse método combina validação de resposta de API com verificações de elementos do DOM, garantindo que tanto os dados quanto o conteúdo visual estejam prontos [1].
sbb-itb-23997f1
Métodos avançados de waitForFunction
Escrevendo condições complexas em JavaScript
Para aplicações web mais dinâmicas, você pode usar waitForFunction para criar condições detalhadas em JavaScript. Veja um exemplo:
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
);
Esse script garante que:
- O contêiner do gráfico exista.
- Haja uma quantidade mínima de pontos de dados.
- Todos os pontos de dados estejam visíveis.
- Nenhum dos pontos esteja em estado de carregamento.
Você também pode combinar verificações assíncronas com avaliações do DOM para fluxos mais complexos:
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
}
);
Essa abordagem combina verificações do DOM com uma chamada de API para garantir que tanto a interface quanto o backend estejam sincronizados.
Lidando com timeouts e erros
O gerenciamento de timeout é fundamental ao trabalhar com waitForFunction. Veja um exemplo de como lidar com timeouts de forma eficiente:
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;
}
Veja uma visão geral rápida das estratégias de timeout:
| Estratégia de timeout | Caso de uso | Configuração |
|---|---|---|
| Timeout padrão | Operações gerais | page.setDefaultTimeout() |
| Timeout de navegação | Carregamentos de página | page.setDefaultNavigationTimeout() |
| Específico por operação | Verificações detalhadas | Use a opção timeout no método |
| Espera infinita | Atrasos conhecidos | timeout: 0 |
Para melhorar o tratamento de erros:
- Ajuste as configurações de timeout com base na complexidade de cada operação.
- Use blocos
try-catchpara se recuperar de erros de forma eficiente. - Monitore a atividade de rede para identificar gargalos.
- Implemente ações de contingência, como recarregar a página, quando ocorrerem timeouts.
- Verifique novamente os seletores para evitar atrasos desnecessários.
Essas práticas ajudam a garantir que seus scripts sejam confiáveis e eficientes.
Como fazer waitForFunction executar mais rápido
Dicas de velocidade e recursos
Para fazer o waitForFunction operar com mais eficiência, concentre-se em estratégias inteligentes de espera e no gerenciamento adequado de recursos. Use as ferramentas de desenvolvedor do navegador para medir tempos de carregamento e definir timeouts 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 reduzir o uso de recursos:
- Bloqueie recursos desnecessários, como imagens ou fontes.
- Use
waitForSelectorouwaitForFunctionem vez dowaitForTimeoutobsoleto. - Combine várias verificações em uma única chamada
evaluatepara reduzir a comunicação entre o navegador e o Node.js.
| Estratégia | Impacto no desempenho | Melhor caso de uso |
|---|---|---|
| networkidle2 | Moderado | Navegação de página |
| waitForSelector | Rápido | Verificações de um único elemento |
| waitForFunction | Variável | Condições complexas |
| evaluate combinado | Mais rápido | Verificações de vários elementos |
Esses métodos podem ajudar a resolver gargalos comuns, abordados na próxima seção.
Corrigindo problemas comuns
Problemas de desempenho geralmente vêm de padrões de espera ineficientes. Veja como lidar com eles:
Problemas com seletores
Seletores excessivamente rígidos podem causar falhas. Simplifique-os para obter mais confiabilidade:
// 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
);
Gerenciamento de recursos
Gerencie recursos e evite atrasos desnecessários:
try {
await page.waitForFunction(
() => document.readyState === 'complete' &&
performance.now() > 1000
);
} catch (error) {
console.error('Page load timeout:', error.message);
}
"O Puppeteer tem uma arquitetura orientada a eventos, o que elimina boa parte da potencial instabilidade. Não há necessidade de chamadas malignas de
sleep[undefined]em scripts do puppeteer." — readme do Puppeteer [6]
Sempre envolva métodos de espera em blocos try...catch para lidar com erros de forma eficiente e oferecer opções de contingência. Essa abordagem garante que seus scripts permaneçam robustos e confiáveis.
Usos comuns de regras de espera personalizadas
Carregamento de produtos em lojas online
Garantir que os produtos sejam carregados corretamente é essencial para coletar dados precisos. Use uma regra de espera personalizada para pausar a execução até que os itens dos produtos estejam totalmente carregados:
await page.waitForFunction(() => {
const products = document.querySelectorAll('.product-card');
return products.length > 0 && all images and prices fully load;
});
Para obter mais precisão, você pode usar esta abordagem:
await page.waitForFunction(() => {
const productDetails = document.querySelector('.product-details');
return productDetails &&
productDetails.offsetHeight > 0 &&
productDetails.querySelector('.inventory-status') !== null;
}, {timeout: 30000});
Isso garante que seu script aguarde o carregamento de todos os elementos necessários, melhorando a confiabilidade da coleta de dados em fluxos de e-commerce.
Carregando conteúdo em aplicações web modernas
Aplicações web dinâmicas geralmente exigem condições de espera específicas para lidar com o carregamento de conteúdo. Por exemplo, você pode aguardar até que um elemento específico se torne totalmente visível:
await page.waitForFunction(() => {
const element = document.querySelector('.tv-lightweight-charts');
return element && element.offsetHeight > 0 && element.offsetWidth > 0;
});
Se várias seções precisarem ser carregadas, combine as condições desta forma:
await page.waitForFunction(() => {
const contentLoaded = document.querySelector('.content').children.length > 0;
const dataUpdated = document.body.textContent.includes('Last updated:');
return contentLoaded && dataUpdated;
}, {polling: 1000});
Esse método ajuda a garantir que seus scripts de automação interajam perfeitamente com conteúdo dinâmico.
Detecção de mensagens de erro em formulários
A detecção de erros em formulários usa uma lógica semelhante às verificações de visibilidade de elementos. Veja como monitorar mensagens de erro:
await page.waitForFunction(() => {
const errorContainer = document.querySelector('.error-messages');
const hasErrors = errorContainer?.children.length > 0;
const isVisible = errorContainer?.offsetParent !== null;
return hasErrors && isVisible;
});
Você também pode acompanhar vários estados de validação de formulários usando condições de espera específicas:
| Tipo de validação | Condição de espera | Caso de uso |
|---|---|---|
| Erros de campo | Verifica a presença de uma classe de erro | Validação de campo individual |
| Erros gerais do formulário | Monitora o contêiner de erros | Status geral do formulário |
| Mensagens de sucesso | Observa a exibição de confirmações | Conclusão do envio |
| Estados de carregamento | Acompanha o estado do botão de envio | Indicação de processamento |
Conclusão
Principais conclusões
O método waitForFunction no Puppeteer avalia condições em JavaScript até que retornem true, oferecendo controle preciso sobre interações em páginas dinâmicas [3].
Estes são alguns dos principais benefícios de usar waitForFunction:
- Avaliação flexível: Lida com funções assíncronas para monitorar estados complexos da página [3].
- Integração de contexto: Permite passar argumentos do Node.js diretamente para o contexto do navegador [3].
- Lógica personalizada: Possibilita uma automação adaptada a condições específicas da página [2].
Essa abordagem é particularmente útil em casos nos quais os métodos de espera padrão não são suficientes. Por exemplo, em aplicações avançadas de página única, vários elementos podem carregar simultaneamente ou estados específicos de JavaScript podem precisar ser confirmados antes de avançar.
Puppeteer e Latenode em ação
A Latenode aproveita o waitForFunction para aprimorar a automação de fluxos. Ao integrar esse método, a Latenode criou um nó de monitoramento personalizado que verifica os status de sites e captura screenshots quando determinadas condições não são atendidas [7].
Veja um exemplo de como a Latenode usa waitForFunction para garantir que elementos críticos sejam totalmente renderizados antes de continuar:
await page.waitForFunction(() => {
const element = document.querySelector('.tv-lightweight-charts');
return element && element.offsetHeight > 0 && element.offsetWidth > 0;
});
Esse trecho aguarda que um elemento com a classe .tv-lightweight-charts não apenas apareça no DOM, mas também seja totalmente renderizado [2].
Para obter os melhores resultados ao usar Latenode com Puppeteer:
- Defina valores de timeout adequados usando
page.setDefaultTimeout(). - Use blocos
try-catchpara um tratamento de erros robusto. - Acompanhe os tempos de execução para ajustar suas condições de espera.


