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
depuração Marionetista scripts podem parecer esmagadores, mas dominar algumas técnicas-chave pode economizar tempo e frustração. Aqui está um rápido resumo do que você aprenderá:
slowMo
modo de navegação e modo de navegação headful para observar seu script em ação.try-catch
blocos e automatizar capturas de tela de erros para melhor solução de problemas.const browser = await puppeteer.launch({
headless: false,
slowMo: 100,
devtools: true
});
DEBUG="puppeteer:*"
para registros detalhados.Ao combinar essas técnicas, você otimizará seu processo de depuração e aumentará a confiabilidade dos seus scripts do Puppeteer.
Configure o Puppeteer para depuração com estas opções de inicialização:
const browser = await puppeteer.launch({
headless: false,
slowMo: 20,
devtools: true
});
Para habilitar o registro detalhado, execute seu script com o seguinte comando:
DEBUG="puppeteer:*" node script.js
Depois de configurado, use ferramentas de depuração para analisar e refinar o comportamento do seu script.
Aqui estão algumas ferramentas para ajudar você a resolver problemas de forma eficaz:
ferramenta | Propósito | Característica chave |
---|---|---|
chromedevtools | Inspecionar scripts | Ferramentas de console e rede |
Código VS Debugger | Gerenciar pontos de interrupção | Execução passo a passo |
Utilitário de captura de tela | Solução de problemas visuais | Capturar estados da página |
Você também pode adicionar pontos de verificação no seu código para melhor visibilidade:
await page.screenshot({ path: 'before_click.png' });
await page.click('#button');
await page.screenshot({ path: 'after_click.png' });
Uma boa organização é tão importante quanto as ferramentas que você usa. Divida seu script em módulos lógicos e inclua tratamento de erros para uma depuração mais suave:
try {
await page.waitForSelector('#target-element');
await page.click('#target-element');
} catch (error) {
console.error(`Navigation failed: ${error.message}`);
await page.screenshot({ path: 'error-state.png' });
}
Para reduzir a chance de detecção de bots, integre o plugin stealth:
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
Por fim, garanta o gerenciamento adequado dos recursos implementando procedimentos de limpeza:
async function cleanup() {
if (page) await page.close();
if (browser) await browser.close();
}
Esta configuração fornece uma base sólida para depuração visual e de console em seus projetos.
Observar seus scripts em ação pode revelar problemas que a análise de código tradicional pode deixar passar. Esses métodos expandem suas opções de depuração além dos logs de console e rastreamento de erros.
O SlowMo introduz um atraso entre as ações do Puppeteer, facilitando o acompanhamento do que está acontecendo:
const browser = await puppeteer.launch({
headless: false,
slowMo: 250,
devtools: true
});
A slowMo
valor (em milissegundos) controla o atraso entre ações. Ajuste-o com base no que você está testando:
Tipo de operação | SlowMo recomendado (ms) | Caso de uso |
---|---|---|
Cliques simples | 100-250 | Passos básicos de navegação |
Preenchimento de formularios | 250-500 | Testando validação de entrada |
Conteúdo dinâmico | 500-1000 | Verificando estados de carregamento |
Depois de configurar o SlowMo, emparelhe-o com o Modo de visualização do navegador para monitorar como a interface do usuário se comporta durante a execução do script.
O Modo de Exibição do Navegador permite que você veja seu script sendo executado em uma janela visível do navegador, o que é especialmente útil para depurar conteúdo dinâmico e interações complexas.
const browser = await puppeteer.launch({
headless: false,
defaultViewport: { width: 1700, height: 800 },
args: ['--start-maximized']
});
Por exemplo, a Acme Corp.A equipe de QA da usou esse modo em junho de 2024 para solucionar problemas de um script de web scraping. Eles identificaram seletores incorretos e os corrigiram, reduzindo o tempo de depuração em 40%.
Para complementar isso, capture capturas de tela de estados visuais importantes para análise posterior.
Capturas de tela e vídeos podem criar um registro claro da execução do seu script, facilitando a depuração:
// Screenshot of a specific element
await page.screenshot({
path: 'element-state.png',
clip: {
x: 0,
y: 0,
width: 500,
height: 300
}
});
// Full-page screenshot
await page.screenshot({
path: 'full-page.png',
fullPage: true
});
Comece habilitando o Modo de Visualização do Navegador, use o SlowMo para rastreamento detalhado e documente os principais momentos com capturas de tela. Juntos, esses passos criam um processo de depuração visual completo.
Os métodos de console fornecem uma maneira direta de obter insights baseados em texto sobre como seus scripts estão se comportando. Essas saídas funcionam junto com a depuração visual para fornecer detalhes precisos sobre a execução do script.
O Puppeteer facilita a captura de mensagens do navegador com manipuladores de eventos como estes:
page.on('console', msg => {
console.log('PAGE LOG:', msg.text());
});
page.on('pageerror', err => {
console.error('PAGE ERROR:', err.message);
});
page.on('requestfailed', request => {
console.error('REQUEST FAILED:', request.url());
});
Esta configuração cria um sistema de registro que rastreia mensagens de console, erros de página e solicitações com falha. Para deixar as coisas mais claras, você pode categorizar mensagens por tipo:
Tipo de mensagem | Propósito | Exemplo de saída |
---|---|---|
Folhas para | Informações gerais | Fluxo de execução padrão |
erro | Problemas maiores | Operações com falha |
Aviso | Preocupações potenciais | Lentidão no desempenho |
Info | Atualizações de status | Conclusão da tarefa |
utilização console.log
sabiamente pode tornar a depuração muito mais fácil. Coloque logs estrategicamente para rastrear o progresso e identificar problemas:
// Log before attempting to find an element
console.log(`Looking for element: ${selector}`);
const element = await page.$(selector);
// Log after confirming the element exists
console.log(`Element found: ${!!element}`);
// Log form data before filling it out
console.log(`Form data: ${JSON.stringify(formData)}`);
await page.type('#email', formData.email);
Para problemas mais complexos, técnicas avançadas de registro podem mudar o jogo:
// Enable detailed debugging for Puppeteer
process.env.DEBUG = 'puppeteer:*';
process.env.DEBUG_MAX_STRING_LENGTH = null;
// Monitor pending protocol calls
const browser = await puppeteer.launch({
dumpio: true
});
console.log(browser.debugInfo.pendingProtocolErrors);
Uma equipe viu uma queda de 40% nas falhas de teste após adotar o registro detalhado de protocolos.
// Filter out specific network domain messages
// Command: DEBUG="puppeteer:*" DEBUG_COLORS=true node script.js 2>&1 | grep -v '"Network'
Esses métodos adicionam uma camada baseada em texto ao seu processo de depuração, ajudando você a detectar e resolver problemas de forma mais eficaz.
A depuração de scripts complexos do Puppeteer envolve o uso de estratégias eficazes de tratamento de erros e técnicas avançadas para garantir que os scripts sejam executados sem problemas.
Use blocos try-catch para gerenciar erros de forma eficaz e manter seu script em execução:
async function navigateAndScreenshot(url, selector) {
try {
await page.goto(url, { waitUntil: 'networkidle0' });
const element = await page.waitForSelector(selector, { timeout: 5000 });
await element.screenshot({ path: 'element.png' });
} catch (error) {
if (error instanceof TimeoutError) {
console.error(`Element ${selector} not found within timeout`);
// Add recovery logic if needed
await page.reload();
} else {
console.error(`Navigation failed: ${error.message}`);
throw error; // Re-throw unexpected errors
}
}
}
Você pode melhorar o tratamento de erros combinando blocos try-catch com classes de erro personalizadas para melhor categorização e resposta.
A criação de classes de erro personalizadas ajuda você a identificar e classificar problemas de forma mais eficiente:
class PuppeteerScriptError extends Error {
constructor(message, details = {}) {
super(message);
this.name = 'PuppeteerScriptError';
this.details = details;
this.timestamp = new Date().toISOString();
}
}
class SelectorError extends PuppeteerScriptError {
constructor(selector, context) {
super(`Failed to find selector: ${selector}`, {
selector,
context,
type: 'SELECTOR_ERROR'
});
this.name = 'SelectorError';
}
}
Essas classes permitem que você rastreie e depure operações assíncronas com mais clareza.
Código assíncrono frequentemente introduz problemas de tempo e promessas não resolvidas. Enfrente esses problemas com as seguintes técnicas:
// Enable detailed debugging for protocol calls
const browser = await puppeteer.launch({
dumpio: true
});
// Monitor unresolved promises periodically
setInterval(() => {
const pending = browser.debugInfo.pendingProtocolErrors;
if (pending.length > 0) {
console.log('Pending protocol calls:', pending);
}
}, 5000);
// Handle async errors with a timeout mechanism
async function safeExecute(promiseFn) {
try {
return await Promise.race([
promiseFn(),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Operation timed out')), 30000)
)
]);
} catch (error) {
console.error(`Operation failed: ${error.message}`);
throw new PuppeteerScriptError('Execution timeout', {
originalError: error,
operation: promiseFn.name
});
}
}
Ao utilizar a blockchain da debugInfo
interface, você pode monitorar retornos de chamada pendentes e identificar promessas não resolvidas durante a comunicação do protocolo do navegador.
Nível de depuração | Propósito | Implementação |
---|---|---|
Basico | Lidar com erros comuns | Blocos try-catch padrão |
Nível intermediário | Classificar erros | Hierarquia de classes de erro personalizada |
Avançado | Problemas de protocolo de rastreamento | Monitoramento de interface de depuração |
Esta seção aborda os desafios frequentes do Puppeteer e fornece correções claras para manter seus scripts de automação funcionando sem problemas.
Problemas de seletor podem frequentemente interromper a execução do script. Veja como lidar com eles efetivamente:
async function findElement(page) {
try {
const element = await page.waitForSelector('[data-testid="target"]', {
timeout: 5000
});
return element;
} catch {
return page.waitForSelector('.target-class', {
timeout: 5000
});
}
}
Para elementos dentro de iframes ou Sombra DOM, use estas abordagens:
// Access iframe content
const frame = await page.frames().find(f => f.name() === 'content-frame');
const button = await frame.$('button[data-hook="create"]');
// Handle Shadow DOM elements
await page.evaluateHandle(selector => {
const element = document.querySelector('parent-element')
.shadowRoot
.querySelector(selector);
return element;
}, 'target-selector');
O manuseio adequado dos seletores garante que seus scripts localizem elementos de forma confiável.
Uma vez que os seletores estejam estáveis, gerenciar o tempo é crucial para uma execução tranquila:
await page.setDefaultNavigationTimeout(30000);
await page.setDefaultTimeout(10000);
async function waitForContent(page) {
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle0' }),
page.click('#load-more-button')
]);
}
Aqui está uma referência rápida para controles de tempo:
Problema de tempo | Solução | Implementação |
---|---|---|
Carregamento de página | esperarPorNavegação | Aguarde a rede ociosa |
Conteúdo Dinâmico | esperarPorSeletor | Use com tempo limite apropriado |
Atualizações AJAX | esperarPorResposta | Monitorar solicitações de rede específicas |
Essas estratégias ajudam a alinhar o tempo do seu script com o comportamento da página.
Mesmo com estratégias sólidas de seletor e tempo, travamentos do navegador ainda podem ocorrer. Veja como minimizar e se recuperar deles:
const browser = await puppeteer.launch({
args: [
'--disable-dev-shm-usage',
'--enable-gpu',
'--no-first-run',
'--disable-extensions'
]
});
Para recuperação de falhas:
let browser;
try {
browser = await puppeteer.launch();
const page = await browser.newPage();
page.on('error', err => {
console.error('Page crashed:', err);
});
await page.goto('https://example.com');
} catch (error) {
console.error('Browser error:', error);
} finally {
if (browser) {
await browser.close();
}
}
Se você estiver trabalhando no Linux, verifique se há dependências ausentes:
ldd chrome | grep not
Para otimizar o uso de recursos, ajuste os sinalizadores do navegador:
const browser = await puppeteer.launch({
args: [
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--disable-gpu'
]
});
Configure a recuperação automática para maior resiliência:
async function checkAndRecoverPage(page) {
if (!page.isClosed()) {
try {
await page.reload();
} catch {
page = await browser.newPage();
}
}
return page;
}
Aprimore seus scripts para facilitar a manutenção e agilizar a resolução de erros com base em técnicas comprovadas de depuração.
Mantenha seu código legível agrupando configurações e usando nomes claros e descritivos:
// Group related configurations
const browserConfig = {
headless: false,
defaultViewport: { width: 1920, height: 1080 },
args: ['--no-sandbox', '--disable-setuid-sandbox']
};
// Use descriptive function names
async function validatePageContent(page) {
const pageTitle = await page.title();
console.log(`Validating content for page: ${pageTitle}`);
const contentExists = await page.evaluate(() => {
const mainContent = document.querySelector('.main-content');
return {
hasHeader: !!document.querySelector('header'),
hasContent: !!mainContent,
contentLength: mainContent?.textContent.length || 0
};
});
return contentExists;
}
Divida seus scripts em módulos separados para simplificar a depuração. Essa abordagem isola seletores, ações e validações, facilitando a localização e a correção de erros.
// selectors.js
export const SELECTORS = {
loginForm: '#login-form',
submitButton: '[data-testid="submit-btn"]',
errorMessage: '.error-notification'
};
// actions.js
export async function performLogin(page, credentials) {
await page.type(SELECTORS.loginForm + ' input[name="username"]', credentials.username);
await page.type(SELECTORS.loginForm + ' input[name="password"]', credentials.password);
await Promise.all([
page.waitForNavigation(),
page.click(SELECTORS.submitButton)
]);
}
// validators.js
export async function checkLoginStatus(page) {
const errorElement = await page.$(SELECTORS.errorMessage);
if (errorElement) {
throw new Error('Login failed: ' + await page.evaluate(el => el.textContent, errorElement));
}
}
Essa estrutura modular não apenas organiza seu código, mas também ajuda a otimizar o rastreamento de erros.
Configure o rastreamento de erros para identificar problemas rapidamente e fornecer contexto detalhado para depuração:
class PuppeteerError extends Error {
constructor(message, action, selector) {
super(message);
this.name = 'PuppeteerError';
this.action = action;
this.selector = selector;
this.timestamp = new Date().toISOString();
}
}
async function executeWithTracking(page, action, description) {
try {
await action();
} catch (error) {
const screenshot = await page.screenshot({
path: `error-${Date.now()}.png`,
fullPage: true
});
throw new PuppeteerError(
`Failed to ${description}`,
error.message,
error.selector
);
}
}
Você também pode automatizar o registro de erros e avisos do console:
page.on('console', message => {
const type = message.type();
const text = message.text();
if (type === 'error' || type === 'warning') {
console.log(`[${type.toUpperCase()}] ${text}`);
// Log to external service or file
logger.log({
level: type,
message: text,
timestamp: new Date().toISOString(),
url: page.url()
});
}
});
Adicione verificações de validação para garantir que operações críticas sejam concluídas com sucesso:
async function validateOperation(page, action) {
const beforeState = await page.evaluate(() => ({
url: window.location.href,
elements: document.querySelectorAll('*').length
}));
await action();
const afterState = await page.evaluate(() => ({
url: window.location.href,
elements: document.querySelectorAll('*').length
}));
return {
urlChanged: beforeState.url !== afterState.url,
elementsDelta: afterState.elements - beforeState.elements
};
}
Essas técnicas, combinadas com métodos de depuração anteriores, ajudam você a identificar e resolver problemas rapidamente, mantendo seus scripts sustentáveis.
Usando depuração visual no modo headful com slowMo
permite feedback imediato sobre scripts e ajustes precisos de tempo. Para cenários mais detalhados, o protocolo DevTools fornece depuração passo a passo e acesso a logs de processo para insights mais profundos.
const browser = await puppeteer.launch({
headless: false,
slowMo: 100,
devtools: true,
dumpio: true
});
Para melhorar seu fluxo de trabalho, considere incorporar práticas de monitoramento contínuo e gerenciamento de recursos junto com esses métodos de depuração.
Agora que você tem uma base sólida em técnicas de depuração, veja como você pode otimizar e manter seus scripts do Puppeteer:
puppeteer-extra-plugin-stealth
plugin para minimizar a detecção de automação e reduzir falhas de script.
Aqui está um exemplo de uma função de limpeza para gerenciar recursos de forma eficaz:
async function cleanupResources(page) {
await page.evaluate(() => {
if (window.performance.memory) {
console.log(`Heap size limit: ${(window.performance.memory.jsHeapSizeLimit / 1024 / 1024).toFixed(2)} MB`);
}
});
await page.close();
}
Fique à frente verificando regularmente o repositório Puppeteer GitHub para atualizações, novos recursos e melhores práticas. Manter seu kit de ferramentas atualizado garante que seus scripts permaneçam eficientes e adaptáveis conforme as tecnologias da web mudam.