
Adélia Cruz
Neural Network Developer

Puppeteer é uma biblioteca JavaScript que fornece uma API de alto nível para controlar o Chrome ou o Firefox usando o Protocolo DevTools ou o WebDriver BiDi.
Originalmente projetado para testes de automação de navegador, o Puppeteer tornou-se uma das ferramentas mais importantes para web scraping moderno devido às suas poderosas capacidades de manipulação de páginas web.
No web scraping tradicional, a maior parte do conteúdo da página é estático e pode ser extraído diretamente solicitando o HTML e analisando-o usando expressões regulares ou ferramentas de análise DOM. No entanto, muitos websites modernos usam JavaScript para carregar dados assincronamente — especialmente aqueles construídos com frameworks como Vue e React, que dependem de Aplicações de Página Única (SPA). Nestes casos, o conteúdo só fica disponível depois que o navegador executa o JavaScript.
O Puppeteer resolve esse desafio controlando diretamente um navegador real. Ele pode simular o comportamento real do usuário, como abrir páginas, aguardar o carregamento completo da página, clicar, digitar, rolar e muito mais — tornando-o ideal para raspar conteúdo renderizado na interface.
Você pode instalar o Puppeteer de duas maneiras:
npm i puppeteer # Isso irá baixar o Puppeteer junto com uma versão compatível do Chromium.
npm i puppeteer-core # Use isso se você já tiver o Chrome instalado e precisar apenas da biblioteca Puppeteer.
No exemplo abaixo, usamos o Puppeteer para navegar até o blog CapSolver e pegar todos os títulos de postagem de blog <h5> da página

const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: false,
args: ['--window-size=1920,1080'],
defaultViewport: null
});
const [page] = await browser.pages();
await page.goto('https://www.capsolver.com/blog/All');
const h5Titles = await page.evaluate(() => {
const headings = Array.from(document.querySelectorAll('h5'));
return headings.map(heading => heading.textContent.trim());
});
console.log(h5Titles);
await browser.close();
})();
Ao controlar uma instância de navegador real, posso esperar que o conteúdo renderizado em JavaScript seja carregado, assim como um usuário regular faria. Isso torna o Puppeteer incrivelmente útil para raspar sites modernos que usam frameworks como Vue ou React.
Um dos recursos poderosos do Puppeteer é seu suporte para carregar extensões de navegador, o que permite a integração com a extensão de navegador CapSolver para resolver desafios de CAPTCHA. Integração passo a passo:
Passo 1. Baixe a extensão CapSolver
Primeiro, baixe a versão mais recente da extensão CapSolver da página oficial de lançamentos do GitHub
Após o download, descompacte o arquivo .zip para obter a pasta da extensão.
Passo 2. Inicie o Puppeteer com a extensão
Agora que você tem a pasta da extensão pronta, você pode carregá-la no Puppeteer usando as sinalizações --disable-extensions-except e --load-extension ao iniciar o navegador:
const puppeteer = require('puppeteer');
// Substitua isso pelo caminho real para sua extensão CapSolver descompactada
const extensionPath = 'path/to/capsolver-extension';
(async () => {
const browser = await puppeteer.launch({
headless: false,
args: [
`--disable-extensions-except=${extensionPath}`,
`--load-extension=${extensionPath}`,
],
});
const [page] = await browser.pages();
await page.goto('https://www.capsolver.com/blog/All');
// Agora você pode usar a funcionalidade da extensão CapSolver nesta sessão
await browser.close();
})();
Tipos de CAPTCHA como reCAPTCHA v2/v3, Cloudflare Turnstile, AWS WAF e Imagetotext são amplamente utilizados em milhares de sites. Apesar de sua popularidade, esses CAPTCHAs normalmente possuem estruturas DOM consistentes e detectáveis. É aí que a Extensão CapSolver entra em ação — ela detecta e resolve automaticamente sem a necessidade de interação manual.
Vamos tomar o reCAPTCHA v2 como exemplo para demonstrar como usar a extensão CapSolver no Puppeteer para resolver captchas (Observação: A menos que especificado de outra forma, os exemplos a seguir são demonstrados no modo de clique: /assets/config.js → reCaptchaMode: 'click').
⚠️ Não se esqueça de descompactar o arquivo zip da extensão e configurar sua
apiKeyem/assets/config.js
const puppeteer = require('puppeteer');
// Passo 1: Obtenha a extensão do github (https://github.com/capsolver/capsolver-browser-extension/releases)
// Passo 2: Descompacte o arquivo zip da extensão e configure sua apiKey em /assets/config.js
const extensionPath = 'path/to/CapSolver Browser Extension-v1.16.0';
(async () => {
const browser = await puppeteer.launch({
headless: false,
args: [
`--disable-extensions-except=${extensionPath}`,
`--load-extension=${extensionPath}`,
`--window-size=1920,1080`,
`--lang=en-US`,
],
defaultViewport: null
});
const [page] = await browser.pages();
await page.goto('https://recaptcha-demo.appspot.com/recaptcha-v2-checkbox.php');
await page.waitForSelector('form[action="/recaptcha-v2-checkbox.php"]');
// A extensão reconhecerá automaticamente o recaptcha e o resolverá.
// Aguarde o captcha ser resolvido e clique no botão de envio.
await new Promise(resolve => setTimeout(resolve, 15000));
await page.click('button[type="submit"]');
await new Promise(resolve => setTimeout(resolve, 5000));
await browser.close();
})();
⚠️ A extensão CapSolver também suporta muitas opções de configuração úteis. Abaixo estão alguns exemplos comuns (Observação: Todas as configurações são definidas em
/assets/config.js)
solvedCallbackComo podemos ver, o código anterior espera 15 segundos após entrar na página antes de clicar em enviar. Esse atraso de 15 segundos destina-se a dar à extensão CapSolver tempo suficiente para resolver automaticamente o reCAPTCHA. No entanto, essa abordagem não é muito elegante, pois o tempo real necessário pode ser muito menor que 15 segundos, ou ainda mais em condições de rede precárias.
O solvedCallback foi projetado para resolver esse problema. Ele aciona um callback assim que o CAPTCHA for resolvido, notificando você de que a verificação está concluída. Você pode encontrar a opção solvedCallback em /assets/config.js e definir um nome de função personalizado — por padrão, é captchaSolvedCallback. Em seguida, use o método page.exposeFunction para expor a função no contexto do navegador.
Vamos otimizar o código anterior usando essa abordagem.
const puppeteer = require('puppeteer');
// Passo 1: Obtenha a extensão do github (https://github.com/capsolver/capsolver-browser-extension/releases)
// Passo 2: Descompacte o arquivo zip da extensão e configure sua apiKey em /assets/config.js
const extensionPath = 'path/to/CapSolver Browser Extension-v1.16.0';
(async () => {
const browser = await puppeteer.launch({
headless: false,
args: [
`--disable-extensions-except=${extensionPath}`,
`--load-extension=${extensionPath}`,
`--window-size=1920,1080`,
`--lang=en-US`,
],
defaultViewport: null
});
const [page] = await browser.pages();
await page.goto('https://recaptcha-demo.appspot.com/recaptcha-v2-checkbox.php');
await page.waitForSelector('form[action="/recaptcha-v2-checkbox.php"]');
// A extensão reconhecerá automaticamente o reCAPTCHA e o resolverá.
// Use solvedCallback para prosseguir somente após o CAPTCHA ser resolvido.
await page.exposeFunction('captchaSolvedCallback', async () => {
console.log('Captcha resolvido!');
// Determine se a verificação ainda é necessária.
const iframe = await page.$('iframe[src*="recaptcha"]');
if (iframe) {
const frame = await iframe.contentFrame();
const finished = await frame.evaluate(() => {
const element = document.querySelector('.recaptcha-checkbox-border');
return element && window.getComputedStyle(element).display === 'none';
});
if (finished) {
console.log('Verificação concluída!');
await page.click('button[type="submit"]');
await new Promise(resolve => setTimeout(resolve, 3000));
await browser.close();
} else {
console.log('Necessário verificar novamente...');
}
}
});
})();
Para o reCAPTCHA v2, às vezes pode pedir que você clique em várias rodadas de imagens. É por isso que, após cada tentativa de verificação, precisamos verificar se a caixa de seleção "Não sou um robô" ainda existe. Se a caixa de seleção não estiver mais presente (ou seja, se tiver se transformado em um ✔️), consideramos a verificação concluída.
manualSolvingNos exemplos anteriores, o processo de resolução do CAPTCHA começa assim que a página carrega. No entanto, em alguns casos, você pode precisar executar outras ações primeiro — como inserir um nome de usuário e senha — antes de acionar a resolução do CAPTCHA. Resolver o CAPTCHA muito cedo pode levar à expiração do token.
manualSolving foi projetado para resolver esse problema. Quando ativado, ele permite que você acione manualmente o processo de resolução do CAPTCHA. Para ativá-lo, defina o seguinte em /assets/config.js:
manualSolving: true
Assim que isso estiver ativado, você pode acionar a resolução do CAPTCHA de duas maneiras:
Simule clicando no botão da extensão CapSolver usando o Puppeteer;
Execute o código a seguir para enviar uma mensagem que aciona a resolução do CAPTCHA:
window.postMessage({ type: 'capsolverSolve' });
⚠️ Observação: Este recurso só é compatível com versões de extensão superiores à v1.16.0!
Aqui está um exemplo completo que demonstra ambos os métodos:
const puppeteer = require('puppeteer');
// Passo 1: Obtenha a extensão do GitHub (https://github.com/capsolver/capsolver-browser-extension/releases)
// Passo 2: Descompacte o arquivo zip da extensão e configure sua apiKey em /assets/config.js
const extensionPath = 'path/to/CapSolver Browser Extension-v1.16.0';
(async () => {
const browser = await puppeteer.launch({
headless: false,
args: [
`--disable-extensions-except=${extensionPath}`,
`--load-extension=${extensionPath}`,
`--window-size=1920,1080`,
`--lang=en-US`,
],
defaultViewport: null
});
const [page] = await browser.pages();
await page.goto('https://recaptcha-demo.appspot.com/recaptcha-v2-checkbox.php');
await page.waitForSelector('form[action="/recaptcha-v2-checkbox.php"]');
// Simule a entrada do usuário
await page.evaluate(() => {
const inputA = document.querySelector('input[name="ex-a"]');
inputA.value = 'username';
const inputB = document.querySelector('input[name="ex-b"]');
inputB.value = 'password';
});
// Simule outras operações
for (let i = 1; i <= 5; i++) {
await new Promise(resolve => setTimeout(resolve, 1000));
console.log(`Esperou ${i} segundos...`);
}
// Acionar a resolução do CAPTCHA (requer manualSolving: true em config.js)
console.log('Iniciando a resolução do CAPTCHA...');
// Método 1: Simule clicando no botão CapSolver
await page.evaluate(() => {
document.querySelector('#capsolver-solver-tip-button').click()
});
// Método 2: Acionar usando postMessage
// await page.evaluate(() => {
// window.postMessage({ type: 'capsolverSolve' });
// });
// Aguarde o CAPTCHA ser resolvido e clique no botão de envio
await page.exposeFunction('captchaSolvedCallback', async () => {
console.log('Captcha resolvido!');
const iframe = await page.$('iframe[src*="recaptcha"]');
if (iframe) {
const frame = await iframe.contentFrame();
const finished = await frame.evaluate(() => {
const element = document.querySelector('.recaptcha-checkbox-border');
return element && window.getComputedStyle(element).display === 'none';
});
if (finished) {
console.log('Verificação concluída!');
await page.click('button[type="submit"]');
await new Promise(resolve => setTimeout(resolve, 3000));
await browser.close();
} else {
console.log('Necessário verificar novamente...');
}
}
});
})();
reCaptchaModeA opção reCaptchaMode inclui dois modos: click e token.
Se você notar que o modo clique requer várias rodadas de cliques na imagem, provavelmente indica que a qualidade do seu ambiente local é ruim. Nesses casos, recomendamos o uso do modo token para melhor desempenho.
| Modo Clique | Modo Token |
|---|---|
![]() |
![]() |
showSolveButtonQuando showSolveButton está definido como false (o padrão é true), o botão CapSolver não será mais exibido na página. No entanto, isso não afetará a funcionalidade normal de resolução de CAPTCHA.

Após definir useProxy: true e especificar proxyType, hostOrIp, port, proxyLogin e proxyPassword, usaremos seu proxy para resolver o captcha. Quando você precisa usar seu próprio proxy? Geralmente, há duas situações:
As opções acima são algumas opções de configuração comuns. Outras opções podem ser definidas de acordo com suas necessidades reais. Se você tiver alguma dúvida, entre em contato com nosso suporte ao cliente.
Ao contrário de captchas de terceiros, como reCAPTCHA, Cloudflare Turnstile, AWS WAF, existe outro tipo de captcha que requer que reconheçamos letras e números de imagens, o que chamamos de ImageToText. Eles são assim:

Os captchas ImageToText são implementados pelos próprios administradores do site. Esses captchas aparecem em posições diferentes em vários sites e páginas, portanto, a extensão CapSolver não consegue identificar automaticamente quais imagens são captchas. Portanto, você precisa informar à extensão CapSolver no seu código fazendo o seguinte:
capsolver-image-to-text-source com o valor 0 no elemento de imagem do captcha;capsolver-image-to-text-result com o valor 0 no elemento onde o resultado é enviado.Tanto capsolver-image-to-text-source quanto capsolver-image-to-text-result podem ser configurados em /assets/config.js como textCaptchaSourceAttribute e textCaptchaResultAttribute, respectivamente.
Vamos usar https://captcha.com/demos/features/captcha-demo.aspx como exemplo para demonstrar como resolver captchas ImageToText no Puppeteer.
Primeiro, verificamos o código-fonte da página da web e localizamos o elemento de imagem do captcha com o id demoCaptcha_CaptchaImage e o elemento da caixa de entrada de resultado com o id captchaCode, como mostrado na figura abaixo:

Então, no código, podemos usar o método setAttribute para adicionar os elementos de localização:
const puppeteer = require('puppeteer');
// Passo 1: Obtenha a extensão do github (https://github.com/capsolver/capsolver-browser-extension/releases)
// Passo 2: Descompacte o arquivo zip da extensão e configure sua apiKey em /assets/config.js
const extensionPath = 'path/to/CapSolver Browser Extension-v1.16.0';
(async () => {
const browser = await puppeteer.launch({
headless: false,
args: [
`--disable-extensions-except=${extensionPath}`,
`--load-extension=${extensionPath}`,
`--window-size=1920,1080`,
`--lang=en-US`,
],
defaultViewport: null
});
const [page] = await browser.pages();
await page.goto('https://captcha.com/demos/features/captcha-demo.aspx');
await page.waitForSelector('#demoCaptcha_CaptchaImage')
// Informe à extensão CapSolver onde a imagem do captcha está localizada na página da web.
await page.evaluate(() => {
const imgElement = document.querySelector('#demoCaptcha_CaptchaImage');
if (imgElement) {
imgElement.setAttribute('capsolver-image-to-text-source', '0');
}
});
// Informe à extensão CapSolver onde o resultado do reconhecimento do captcha deve ser preenchido na página da web.
await page.evaluate(() => {
const resultElement = document.querySelector('#captchaCode');
if (resultElement) {
resultElement.setAttribute('capsolver-image-to-text-result', '0');
}
});
// Aguarde o captcha ser resolvido e clique no botão de validação.
await page.exposeFunction('captchaSolvedCallback', async () => {
console.log('Captcha resolvido!');
await new Promise(resolve => setTimeout(resolve, 3000));
await page.click('#validateCaptchaButton');
await new Promise(resolve => setTimeout(resolve, 3000));
await browser.close();
});
})();
Efeito alcançado:

Usar a extensão CapSolver é conveniente e rápido, mas se você é um desenvolvedor experiente, recomendamos usar a integração da API. Em comparação com a extensão, a integração da API tem as seguintes vantagens:
Antes de demonstrarmos o código, você precisa entender como nossa API funciona, que envolve principalmente duas etapas:
Criar uma tarefa geralmente requer o envio de dados JSON para o CapSolver. Os dados JSON incluem seu clientKey, websiteURL, websiteKey e outras informações. Diferentes tipos de captcha e sites exigem dados diferentes. Para informações detalhadas, consulte nossa documentação
Antes de resolver o reCAPTCHA v2, consulte a documentação: ReCaptchaV2. A documentação explica detalhadamente quais dados JSON você deve enviar para o CapSolver. Além disso, você pode usar a extensão CapSolver para obter rapidamente os dados JSON
Tomando https://recaptcha-demo.appspot.com/recaptcha-v2-checkbox.php como exemplo, os dados JSON necessários são:
{
"type": "ReCaptchaV2TaskProxyLess",
"websiteKey": "6LfW6wATAAAAAHLqO2pb8bDBahxlMxNdo9g947u9",
"websiteURL": "https://recaptcha-demo.appspot.com/recaptcha-v2-checkbox.php"
}
Também fornecemos um exemplo JS de como usar a API em nossa documentação para sua referência:

Integrando no Puppeteer:
const puppeteer = require('puppeteer');
const axios = require('axios');
// Substitua pela sua chave de API
const api_key = 'YOUR_API_KEY';
const captcha_type = 'ReCaptchaV2TaskProxyLess';
const site_key = '6LfW6wATAAAAAHLqO2pb8bDBahxlMxNdo9g947u9';
const site_url = 'https://recaptcha-demo.appspot.com/recaptcha-v2-checkbox.php';
async function capSolver() {
const payload = {
clientKey: api_key,
task: {
type: captcha_type,
websiteKey: site_key,
websiteURL: site_url
}
};
try {
const res = await axios.post('https://api.capsolver.com/createTask', payload);
const task_id = res.data.taskId;
if (!task_id) {
console.log('Falha ao criar tarefa:', res.data);
return;
}
console.log('Obteve taskId:', task_id);
while (true) {
await new Promise(resolve => setTimeout(resolve, 1000)); // Atraso de 1 segundo
const getResultPayload = { clientKey: api_key, taskId: task_id };
const resp = await axios.post('https://api.capsolver.com/getTaskResult', getResultPayload);
const status = resp.data.status;
if (status === 'ready') {
return resp.data.solution.gRecaptchaResponse;
}
if (status === 'failed' || resp.data.errorId) {
console.log('Resolução falhou! resposta:', resp.data);
return;
}
}
} catch (error) {
console.error('Erro:', error);
}
}
(async () => {
const browser = await puppeteer.launch({
headless: false,
args: [
'--window-size=1920,1080',
'--lang=en-US',
],
defaultViewport: null
});
const [page] = await browser.pages();
await page.goto('https://recaptcha-demo.appspot.com/recaptcha-v2-checkbox.php');
await page.waitForSelector('form[action="/recaptcha-v2-checkbox.php"]');
const token = await capSolver();
console.log("Token:", token);
// Define o valor do token
await page.evaluate((token) => {
const textarea = document.getElementById('g-recaptcha-response');
if (textarea) {
textarea.value = token;
}
}, token);
await page.click('button[type="submit"]');
await new Promise(resolve => setTimeout(resolve, 5000));
await browser.close();
})();
Tomando https://captcha.com/demos/features/captcha-demo.aspx como exemplo, localizamos o elemento de imagem do captcha com o id demoCaptcha_CaptchaImage e o elemento de entrada de resultado com o id captchaCode, como mostrado na imagem abaixo:

Para a ImageToTextTask, precisamos enviar o valor base64 da imagem do captcha para o CapSolver. O código de exemplo é o seguinte:
const puppeteer = require('puppeteer');
const axios = require('axios');
// Substitua pela sua chave de API
const api_key = 'YOUR_API_KEY';
const captcha_type = 'ImageToTextTask';
const site_url = 'https://captcha.com/demos/features/captcha-demo.aspx';
async function capSolver(base64Image) {
const payload = {
clientKey: api_key,
task: {
type: captcha_type,
websiteURL: site_url,
body: base64Image,
}
};
try {
const res = await axios.post('https://api.capsolver.com/createTask', payload);
const status = res.data.status;
if (status === 'ready') {
return res.data.solution.text;
}
if (status === 'failed' || res.data.errorId) {
console.log('Resolução falhou! resposta:', res.data);
return "";
}
} catch (error) {
console.error('Erro:', error);
}
}
(async () => {
const browser = await puppeteer.launch({
headless: false,
args: [
'--window-size=1920,1080',
'--lang=en-US',
],
defaultViewport: null
});
const [page] = await browser.pages();
await page.goto('https://captcha.com/demos/features/captcha-demo.aspx');
await page.waitForSelector('#demoCaptcha_CaptchaImage');
// Obtenha o valor base64 da imagem do captcha
const captchaImage = await page.evaluate(() => {
const img = document.querySelector('img[id="demoCaptcha_CaptchaImage"]');
return img ? img.getAttribute('src') : null;
});
const base64Image = captchaImage.split(',')[1];
const text = await capSolver(base64Image);
console.log("Texto:", text);
// Define o valor do texto reconhecido
await page.evaluate((text) => {
document.getElementById('captchaCode').value = text;
}, text);
await page.click('#validateCaptchaButton');
await new Promise(resolve => setTimeout(resolve, 5000));
await browser.close();
})();
Além disso, para alguns tipos especiais de ImageToText, você pode especificar modelos diferentes para melhorar a precisão. Para detalhes, consulte nossa documentação:
https://docs.capsolver.com/en/guide/recognition/ImageToTextTask/

Para ajudá-lo a aproveitar ao máximo o CapSolver, aqui estão alguns recursos essenciais:
Vídeos de demonstração com a extensão CapSolver:
Aqui estão algumas opções de configuração poderosas que você pode aproveitar para uma resolução de captcha ainda melhor:
| Opção de Configuração | Propósito |
|---|---|
solvedCallback |
Callback acionado quando o CAPTCHA é resolvido com sucesso |
manualSolving |
Ativa o atraso para que a resolução só comece quando acionada explicitamente |
reCaptchaMode |
Escolha entre resolver por “clique” ou por “token” |
useProxy |
Ativa o uso do seu próprio proxy durante a resolução do captcha |
textCaptchaSourceAttribute |
Atributo personalizado para marcar elementos de imagem de captcha (ImageToText) |
| textCaptchaResultAttribute | Atributo personalizado para marcar campos de entrada onde os resultados do captcha vão |
Adicionalmente, a CapSolver oferece um Programa de Compartilhamento de Receita para Desenvolvedores, permitindo que desenvolvedores e parceiros ganhem comissões integrando ou promovendo soluções CapSolver. É uma ótima maneira de monetizar seu trabalho enquanto ajuda outros a resolver captchas eficientemente. Para detalhes completos, confira:
Plano para Desenvolvedores CapSolver
Ao integrar a API da CapSolver com o Puppeteer como demonstrado, você obtém controle total, flexibilidade e feedback detalhado de erros — perfeito para desenvolvedores que procuram uma solução robusta e escalável além de extensões de navegador.
Para mais detalhes e uso avançado, certifique-se de verificar a documentação oficial e os tutoriais vinculados acima.
Obrigado por escolher CapSolver! Se você tiver alguma dúvida ou precisar de suporte, nossa equipe está sempre pronta para ajudar.
Guia de captcha para fluxos de trabalho de dados aprovados: aprenda os tipos de desafios, tratamento de API, consistência de proxies, tentativas de repetição e uso responsável.

API de resolução rápida de CAPTCHA para automação: compare fluxos de trabalho de tokens, desafios suportados, verificações de latência e integração responsável da CapSolver.
