Preços
PRODUTO
SOLUÇÕES
por casos de uso
AI Gestão de leadsFacturaçãoMídia socialGestão de ProjetosGestão de dadospor setor
saber mais
BlogModelosVÍDEOSYoutubeRECURSOS
COMUNIDADES E MÍDIAS SOCIAIS
PARCEIROS
page.evaluate()
é uma chave Marionetista método que permite executar JavaScript diretamente no contexto do navegador. Ele faz a ponte Node.js e o navegador, permitindo tarefas como manipulação de DOM, extração de dados e automação de páginas web dinâmicas. Aqui está o que você precisa saber:
const title = await page.evaluate(() => document.title);
Isso recupera o título da página diretamente do navegador.
Característica | Contexto Node.js | Contexto do navegador |
---|---|---|
Objetos Globais | process , require |
window , document |
Localização do script | Máquina local | Página da web de destino |
Acesso API | APIs do Node.js | APIs da Web do navegador |
Use page.evaluate()
para tarefas de automação precisas e eficientes, especialmente ao trabalhar com sites com uso intenso de JavaScript.
Ao trabalhar com o Puppeteer para automação web, é crucial entender a distinção entre Contexto Node.js e os votos de contexto do navegador. Esses dois ambientes são isolados, cada um com suas próprias regras para executar código e trocar dados.
O marionetista opera em dois ambientes: o Contexto Node.js, onde seu script principal é executado e o contexto do navegador, onde ocorrem interações com a página da web. Esses são processos separados, cada um com sua própria máquina virtual.
Aqui está uma rápida comparação de suas principais características:
Característica | Contexto Node.js | Contexto do navegador |
---|---|---|
Objetos Globais | process , require , __dirname |
window , document , localStorage |
Localização do script | Máquina local | Página da web de destino |
Escopo Variável | Escopo do script do marionetista | Âmbito do contexto da página |
Acesso API | APIs do Node.js | APIs da Web do navegador |
Espaço de Memória | Processo separado | Processo do navegador |
A troca de dados entre esses contextos envolve uma série de etapas, dependendo fortemente da serialização:
Function.prototype.toString()
.Principais limitações: Funções no contexto do navegador não podem acessar variáveis diretamente do escopo do Node.js. O Puppeteer oferece ferramentas específicas para lidar com esses desafios:
page.evaluateHandle()
: Retorna referências a objetos no contexto do navegador.page.exposeFunction()
: Permite que o navegador chame funções do Node.js.evaluateOnNewDocument()
: Executa o código antes que qualquer script de página seja carregado.No entanto, a serialização JSON pode remover certas propriedades, especialmente com objetos complexos como nós DOM. Para evitar problemas, passe dados como argumentos de função em vez de depender de variáveis Node.js.
Dominar essas técnicas de comunicação garante que você possa usar page.evaluate
efetivamente para tarefas de automação. Em seguida, vamos mergulhar em exemplos práticos para ver esses conceitos em ação.
Sintaxe:
await page.evaluate(pageFunction, ...args)
Parâmetro | Formato | Descrição |
---|---|---|
pageFunção | Função ou string | Código JavaScript para executar no contexto do navegador |
args | Parâmetros opcionais | Valores passados do Node.js para o contexto do navegador |
Valor de retorno | Promessa | Resolve com o valor de retorno da função |
A pageFunção pode ser uma função ou uma string contendo código JavaScript. Usar uma função geralmente é melhor para depuração e TypeScript compatibilidade. Abaixo estão alguns exemplos para demonstrar como funciona.
Exemplos:
<h1>
diretamente do DOM:const headingText = await page.evaluate(() => {
return document.querySelector('h1').textContent;
});
await page.evaluate((username, password) => {
document.getElementById('username').value = username;
document.getElementById('password').value = password;
document.querySelector('#login-form').submit();
}, 'myUsername', 'myPassword');
await page.evaluate(() => {
const div = document.createElement('div');
div.textContent = 'Added by Puppeteer';
document.body.appendChild(div);
return div.textContent;
});
Dica de depuração: Use a seguinte configuração para habilitar a depuração durante o desenvolvimento:
const browser = await puppeteer.launch({
headless: false,
slowMo: 100 // Adds a 100ms delay to each operation
});
Em seguida, veremos técnicas para troca de dados entre o Node.js e contextos de navegador.
Ao transferir dados com page.evaluate
, use valores serializáveis em JSON para argumentos de entrada.
Aqui está uma rápida análise dos tipos de parâmetros suportados:
Tipo de Parâmetro | Suportado? | Exemplo |
---|---|---|
Primitivos | ✓ Totalmente | 'text' , 42 , true |
Matrizes/Objetos | ✓ Compatível com JSON | { key: 'value' } , [1, 2, 3] |
Funções | ✗ Não diretamente | Use page.exposeFunction |
Elementos DOM | ✓ Através do JSHandle | Use page.evaluateHandle |
Agora, vamos ver como esses valores são retornados do contexto do navegador.
Ao usar page.evaluate
, os valores retornados são serializados automaticamente para JSON. Veja como funciona:
// Returning a simple value
const pageTitle = await page.evaluate(() => document.title);
// Returning a complex object
const metrics = await page.evaluate(() => ({
viewport: window.innerWidth,
scrollHeight: document.body.scrollHeight,
timestamp: Date.now()
}));
"Como regra geral, se o valor de retorno da função fornecida for mais complicado do que um objeto JSON (por exemplo, a maioria das classes), então
evaluate
provavelmente retornará algum valor truncado (ou{}
). Isso ocorre porque não estamos retornando o valor de retorno real, mas uma versão desserializada como resultado da transferência do valor de retorno por meio de um protocolo para o Puppeteer."
Após recuperar a saída, você pode encontrar desafios relacionados à serialização. Veja como lidar com eles.
Alguns cenários comuns exigem soluções alternativas específicas:
const bodyHandle = await page.$('body');
const html = await page.evaluate(body => body.innerHTML, bodyHandle);
await bodyHandle.dispose(); // Always clean up to avoid memory leaks
await page.exposeFunction('md5', text =>
crypto.createHash('md5').update(text).digest('hex')
);
const hash = await page.evaluate(async () => {
return await window.md5('test-string');
});
Se você estiver trabalhando com TypeScript, certifique-se de que seu transpilador esteja configurado corretamente:
// tsconfig.json
{
"compilerOptions": {
"target": "es2018"
}
}
Essas estratégias ajudarão você a lidar com a troca de dados de forma eficaz em vários contextos.
Veja como você pode usar page.evaluate
em cenários do mundo real, completos com trechos de código práticos.
Exemplo: raspagem de detalhes do produto
Este script coleta detalhes como título, preço, classificação e status de estoque de cartões de produtos em uma página da web:
const productData = await page.evaluate(() => {
const products = Array.from(document.querySelectorAll('.product-card'));
return products.map(product => ({
title: product.querySelector('.title').textContent.trim(),
price: product.querySelector('.price').textContent.trim(),
rating: parseFloat(product.querySelector('.rating').dataset.value),
inStock: product.querySelector('.stock').textContent.includes('Available')
}));
});
Exemplo: Extraindo dados da tabela
Essa abordagem recupera dados de uma tabela iterando por suas linhas e colunas:
const tableData = await page.evaluate(() => {
const rows = Array.from(document.querySelectorAll('table tr'));
return rows.map(row => {
const columns = row.querySelectorAll('td');
return Array.from(columns, column => column.innerText);
});
});
Automação básica de formulários
Veja como preencher campos de formulário, acionar eventos e enviar o formulário:
await page.evaluate(() => {
// Fill form fields
document.querySelector('#username').value = 'testuser';
document.querySelector('#password').value = 'secretpass';
// Trigger input events for dynamic forms
const event = new Event('input', { bubbles: true });
document.querySelector('#username').dispatchEvent(event);
// Submit form
document.querySelector('form').submit();
});
Manipulando formulários complexos
Para tarefas como selecionar opções suspensas ou verificar botões de opção:
await page.evaluate(() => {
// Select dropdown option
const select = document.querySelector('#country');
select.value = 'US';
select.dispatchEvent(new Event('change', { bubbles: true }));
// Check radio button
const radio = document.querySelector('input[value="express"]');
radio.checked = true;
radio.dispatchEvent(new Event('change', { bubbles: true }));
});
Exemplo: rolagem infinita
Este script rola por uma página até coletar pelo menos 100 itens:
const items = await page.evaluate(async () => {
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
const items = new Set();
while (items.size < 100) {
// Scroll to bottom
window.scrollTo(0, document.body.scrollHeight);
// Wait for new content
await delay(1000);
// Collect items
document.querySelectorAll('.item').forEach(item =>
items.add(item.textContent.trim())
);
}
return Array.from(items);
});
Exemplo: Manipulando conteúdo AJAX
Para carregar mais conteúdo dinamicamente, este script clica no botão "Carregar mais" e aguarda que novos elementos apareçam:
await page.evaluate(async () => {
// Click load more button
document.querySelector('#loadMore').click();
// Wait for content update
await new Promise(resolve => {
const observer = new MutationObserver((mutations, obs) => {
if (document.querySelectorAll('.item').length > 10) {
obs.disconnect();
resolve();
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
});
Esses exemplos mostram como lidar com cenários diversos, como scraping, automação de formulários e conteúdo dinâmico. Ajustes podem ser feitos com base na estrutura e no comportamento específicos da página da web com a qual você está trabalhando.
O Latenode incorpora os principais recursos do Puppeteer em seus fluxos de trabalho de automação, facilitando a execução de JavaScript diretamente no navegador. Com page.evaluate
, os usuários podem manipular o DOM e extrair dados de forma eficiente. Essa abordagem permite integração perfeita de manipulação avançada de dados e operações DOM dentro do ambiente de automação do Latenode.
O módulo de automação do navegador do Latenode usa page.evaluate
para lidar com tudo, desde tarefas simples de DOM até execuções mais complexas de JavaScript. Veja como funciona em diferentes cenários:
// Basic DOM interaction
await page.evaluate(() => {
const loginButton = document.querySelector('#login');
loginButton.click();
// Trigger a custom event
loginButton.dispatchEvent(new Event('customClick'));
});
// Processing data with exposed functions
await page.exposeFunction('processData', async (data) => {
// Process data in Node.js context
return transformedData;
});
await page.evaluate(async () => {
const rawData = document.querySelector('#data').textContent;
const processed = await window.processData(rawData);
return processed;
});
O Latenode também mantém um registro do histórico de execução, facilitando a depuração de scripts.
O Latenode é bem equipado para lidar com conteúdo dinâmico e tarefas complexas de automação. Aqui está um exemplo de processamento de conteúdo dinâmico em uma página:
const extractProductData = await page.evaluate(async () => {
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
// Wait for dynamic content to load
while (!document.querySelector('.product-grid')) {
await delay(100);
}
return Array.from(document.querySelectorAll('.product'))
.map(product => ({
name: product.querySelector('.name').textContent,
price: product.querySelector('.price').textContent,
availability: product.querySelector('.stock').dataset.status
}));
});
Para operações mais avançadas, page.exposeFunction
permite interação perfeita entre o Node.js e o navegador:
await page.exposeFunction('md5', text =>
crypto.createHash('md5').update(text).digest('hex')
);
const processedData = await page.evaluate(async () => {
const sensitiveData = document.querySelector('#secure-data').value;
return await window.md5(sensitiveData);
});
Para manter referências aos elementos DOM em todas as etapas, o Latenode usa page.evaluateHandle
:
const elementHandle = await page.evaluateHandle(() => {
return document.querySelector('.dynamic-content');
});
await page.evaluate(element => {
element.scrollIntoView();
}, elementHandle);
Essas técnicas garantem que o Latenode possa lidar com conteúdo dinâmico de forma eficaz, mantendo um desempenho confiável. Para usuários no plano Prime, a plataforma suporta até 1.5 milhão de execuções de cenário por mês, fornecendo amplos recursos de automação.
Ao trabalhar com page.evaluate
na automação do navegador, você pode encontrar vários problemas. Aqui estão soluções práticas para lidar com eles e garantir uma execução mais suave.
Configure corretamente suas configurações de TypeScript para evitar problemas causados pela transpilação. Por exemplo:
// Use direct, non-transpiled functions
await page.evaluate(() => {
document.querySelector('#button').click();
});
await page.evaluate(`(async () => {
document.querySelector('#button').click();
})()`);
Evite retornar elementos DOM diretamente de page.evaluate
. Em vez disso, use ElementHandle
para melhor manuseio:
// Incorrect: Returning a DOM element
const element = await page.evaluate(() => {
return document.querySelector('.dynamic-element');
});
// Correct: Using ElementHandle
const element = await page.evaluateHandle(() => {
return document.querySelector('.dynamic-element');
});
Scripts podem ser executados antes que a página seja totalmente carregada, levando a erros de tempo. Use estas estratégias para lidar com tais casos:
// Wait for navigation after an action
await Promise.all([
page.waitForNavigation(),
page.click('#submit-button')
]);
// Wait for a specific condition
await page.waitForFunction(() => {
const element = document.querySelector('.lazy-loaded');
return element && element.dataset.loaded === 'true';
}, { timeout: 5000 });
Para sites dinâmicos, adote mecanismos de espera mais direcionados:
// Wait for specific network requests
await page.waitForResponse(
response => response.url().includes('/api/data')
);
// Ensure elements are both present and visible
await page.waitForSelector('.dynamic-content', {
visible: true,
timeout: 3000
});
Para evitar vazamentos de memória, gerencie cuidadosamente as referências DOM. Veja como:
// Use and dispose ElementHandles
const handle = await page.evaluateHandle(() => {
return document.querySelector('.temporary-element');
});
await handle.evaluate(element => {
// Perform operations
});
await handle.dispose(); // Dispose of handle after use
Ao trabalhar com vários elementos, passe dados com segurança entre contextos:
// Extract data from the DOM
const selector = '.product-price';
const price = await page.evaluate((sel) => {
const element = document.querySelector(sel);
return element ? element.textContent.trim() : null;
}, selector);
Para ouvintes de eventos, garanta uma limpeza adequada para evitar manipuladores persistentes:
await page.evaluate(() => {
const handler = () => console.log('clicked');
const button = document.querySelector('#button');
button.addEventListener('click', handler);
// Store cleanup references
window._cleanupHandlers = window._cleanupHandlers || [];
window._cleanupHandlers.push(() => {
button.removeEventListener('click', handler);
});
});
Para obter os melhores resultados com page.evaluate
, você precisa se concentrar em melhorar o desempenho, reduzir a troca desnecessária de contexto e garantir a segurança. Veja como você pode ajustar seus fluxos de trabalho de automação do navegador.
Executar código eficientemente dentro do contexto da página economiza tempo e recursos do sistema. Abaixo estão algumas técnicas para tornar seus scripts mais rápidos:
// Block unnecessary resources like images and stylesheets
await page.setRequestInterception(true);
page.on('request', request => {
if (['image', 'stylesheet'].includes(request.resourceType())) {
request.abort();
} else {
request.continue();
}
});
// Batch operations to reduce overhead
await page.evaluate(() => {
const results = [];
document.querySelectorAll('.product-item').forEach(item => {
results.push({
title: item.querySelector('.title').textContent,
price: item.querySelector('.price').textContent,
stock: item.querySelector('.stock').dataset.value
});
});
return results;
});
A escolha dos seletores certos também desempenha um papel importante no desempenho:
Tipo de seletor | Velocidade | Exemplo |
---|---|---|
ID | Fastest | #main-content |
Aula | pomposidade | .product-item |
etiqueta | Moderado | div > span |
XPath complexo | Mais lento | //div[@class='wrapper']//span |
A troca de contexto entre o Node.js e o ambiente do navegador pode deixar as coisas lentas. Veja como minimizá-la:
// Example of inefficient context switching
for (const item of items) {
await page.evaluate((i) => {
document.querySelector(`#item-${i}`).click();
}, item);
}
// Better: Batch operations in a single context switch
await page.evaluate((itemsList) => {
itemsList.forEach(i => {
document.querySelector(`#item-${i}`).click();
});
}, items);
Se você precisar processar dados no Node.js e passá-los de volta para o navegador, exponha funções em vez de alternar contextos repetidamente:
await page.exposeFunction('processData', async (data) => {
// Process data in Node.js
return transformedData;
});
await page.evaluate(async () => {
const result = await window.processData(documentData);
// Use the processed data in the browser
});
Depois que o desempenho e a troca de contexto forem otimizados, concentre-se em manter seus scripts seguros. Aqui estão algumas práticas recomendadas:
// Always sanitize inputs before using them
const sanitizedInput = sanitizeHtml(userInput);
await page.evaluate((input) => {
document.querySelector('#search').value = input;
}, sanitizedInput);
// Use error handling for critical operations
try {
await page.evaluate(() => {
if (!window.__securityCheck) {
throw new Error('Security check failed');
}
// Continue with the operation
});
} catch (error) {
console.error('Security violation:', error);
}
Para fluxos de trabalho do Latenode, considere estas dicas adicionais:
userDataDir
para armazenar recursos em cache e melhorar o desempenho entre sessões.A page.evaluate
O método conecta o Node.js e os contextos do navegador enviando uma função JavaScript stringificada para executar no navegador. Essa função opera independentemente do ambiente do Node.js, então você precisa lidar com a transferência de dados com cuidado.
Aqui está um exemplo comum para extração de dados:
const data = await page.evaluate(async () => {
const results = document.querySelectorAll('.data-item');
return Array.from(results, item => ({
id: item.dataset.id,
value: item.textContent.trim()
}));
});
Coisas a ter em mente:
evaluate
contexto.Esses princípios básicos estabelecem a base para usar o Puppeteer de forma eficaz. Ferramentas adicionais podem simplificar ainda mais suas tarefas de automação.
O Puppeteer oferece diversas ferramentas para expandir as capacidades do page.evaluate
:
ferramenta | Propósito | Melhor caso de uso |
---|---|---|
page.evaluateHandle |
Retorna referências de objeto | Interagindo com elementos DOM diretamente |
page.exposeFunction |
Torna as funções do Node.js utilizáveis no navegador | Gerenciando lógica complexa do lado do servidor |
page.evaluateOnNewDocument |
Executa scripts antes do carregamento de uma página | Preparando o ambiente do navegador com antecedência |
Por exemplo, expor funções do Node.js ao navegador pode simplificar o processamento avançado de dados em fluxos de trabalho como aqueles no Latenode. Enquanto page.evaluate
funciona bem para manipular tipos primitivos e objetos serializáveis JSON, page.evaluateHandle
é essencial para lidar com objetos complexos do navegador que não podem ser serializados.