Se a pontuação do reCAPTCHA v3 nunca passa de 0,3 na sua automação, o culpado geralmente não é o proxy — é o modo do Chrome. Headless é rápido e leve, mas expõe sinais que sistemas anti-bot detectam em milissegundos; headed passa por navegador real, ao custo de mais RAM. Veja o que muda entre os dois modos e como resolver o CAPTCHA da mesma forma em qualquer um deles, com a API da CaptchaAI.
Chrome headless x headed: comparação rápida
Antes de entrar no código, veja o que muda na prática entre os dois modos:
| Fator | Chrome headless | Chrome headed |
|---|---|---|
| Velocidade | Rápida (sem custo de renderização) | Mais lenta (renderiza a interface) |
| Memória | ~100–200 MB | ~300–500 MB |
| Deploy em servidor | Nativo, sem dependências extras | Exige display virtual (Xvfb) |
| Detecção de CAPTCHA | Alta (expõe sinais de automação) | Baixa (comportamento de navegador real) |
| Pontuação reCAPTCHA v3 | 0,1–0,3 (faixa de bot) | 0,7–0,9 (faixa humana) |
| Depuração | Mais difícil (sem interface visual) | Fácil (acompanha a página) |
| Escalonamento | Excelente (poucos recursos) | Consome mais recursos por sessão |
Qual modo escolher em cada cenário
A resposta certa depende do volume de sessões, do orçamento de infraestrutura e de quanto a pontuação do reCAPTCHA v3 importa para o seu fluxo:
| Cenário | Headless | Headed | Headed + Xvfb |
|---|---|---|---|
| Servidor ou CI sem display | Ideal | Exige display | Funciona (2x memória) |
| Mais de 50 sessões simultâneas | Ideal | Custoso | Custoso |
| Depurar o fluxo visualmente | Difícil | Ideal | Ideal |
| Pontuação reCAPTCHA v3 crítica | Fraca | Forte | Boa |
| Site bloqueia headless especificamente | Falha | Ideal | Ideal |
| Memória limitada por sessão | Ideal | Cara | Cara |
A CaptchaAI resolve nos três cenários; a tabela é só sobre o navegador.
Como o CAPTCHA identifica o Chrome headless
reCAPTCHA e Cloudflare rodam testes de JavaScript assim que a página carrega — nenhum deles depende de IP ou de proxy.
Sinais de detecção
// Tests that CAPTCHA systems run
// 1. WebDriver flag (biggest tell)
sinal de navegador automatizado // true in headless, undefined in real browser
// 2. Chrome object completeness
window.chrome // Missing or incomplete in headless
// 3. Plugins
navigator.plugins.length // 0 in headless, 3+ in headed
// 4. WebGL renderer
// Headless: "SwiftShader Renderer"
// Headed: "ANGLE (NVIDIA GeForce GTX 1080...)"
// 5. User-Agent contains "Headless"
navigator.userAgent.includes("Headless") // Old Chrome versions
// 6. Screen dimensions
screen.width === 0 // Some headless configs
// 7. Notification permission
Notification.permission // "denied" in headless without override
Resultado dos testes por modo
Signal Headed Headless New Headless (v112+)
─────────────────────────────────────────────────────────────
webdriver false true true
chrome object full partial improved
plugins 5 0 0
WebGL renderer ANGLE Swift Swift
screen.width 1920 800 800
UA "HeadlessChrome" no yes no (removed)
O modo headless "new" do Chrome reduz a detecção?
A partir da versão 112, o Chrome trouxe o --headless=new, que renderiza a página com o mesmo motor do modo headed:
from selenium import webdriver
# Old headless (more detectable)
options = webdriver.ChromeOptions()
options.add_argument("--headless") # Legacy mode
# New headless (less detectable)
options = webdriver.ChromeOptions()
options.add_argument("--headless=new") # Shares headed rendering
driver = webdriver.Chrome(options=options)
O novo modo corrige parte dos vetores, mas ainda expõe o sinalizador webdriver e continua sem plugins.
Resolvendo CAPTCHA em modo headless com a CaptchaAI (Python)
A CaptchaAI resolve o desafio no lado do servidor a partir da sitekey e da URL da página — o modo do navegador que fez a requisição não interfere no resultado:
import requests
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
API_KEY = "YOUR_API_KEY"
API_URL = "https://ocr.captchaai.com"
def create_headless_driver():
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--no-sandbox")
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument("--window-size=1920,1080")
options.add_argument(
"--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
)
return webdriver.Chrome(options=options)
def solve_captcha(site_url, sitekey):
resp = requests.post(f"{API_URL}/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": site_url,
"json": 1,
})
task_id = resp.json()["request"]
for _ in range(60):
time.sleep(5)
resp = requests.get(f"{API_URL}/res.php", params={
"key": API_KEY, "action": "get",
"id": task_id, "json": 1,
})
data = resp.json()
if data["request"] != "CAPCHA_NOT_READY":
return data["request"]
raise TimeoutError("Solve timeout")
# Full headless workflow
driver = create_headless_driver()
try:
driver.get("https://example.com/form")
time.sleep(2)
sitekey = driver.execute_script(
"return document.querySelector('[data-sitekey]')?.getAttribute('data-sitekey')"
)
if sitekey:
token = solve_captcha(driver.current_url, sitekey)
driver.execute_script(f"""
document.querySelector('#g-recaptcha-response').value = '{token}';
""")
driver.find_element(By.CSS_SELECTOR, "form").submit()
finally:
driver.quit()
Capture a sitekey, envie para in.php e injete o token retornado — em qualquer modo de navegador.
Chrome headed em servidor: como configurar o Xvfb
Sem display físico, o Xvfb cria um display virtual e o Chrome roda em modo headed — inclusive em workers na região sa-east-1 (São Paulo).
Linux com Xvfb
# Install
sudo apt-get install xvfb
# Run with virtual display
xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24" python script.py
Python com PyVirtualDisplay
from pyvirtualdisplay import Display
from selenium import webdriver
display = Display(visible=0, size=(1920, 1080))
display.start()
options = webdriver.ChromeOptions()
# No --headless flag = headed mode in virtual display
options.add_argument("--no-sandbox")
options.add_argument("--window-size=1920,1080")
driver = webdriver.Chrome(options=options)
# Now runs headed Chrome with real rendering, but no physical display
Docker com Xvfb
FROM python:3.12-slim
RUN apt-get update && apt-get install -y \
xvfb \
chromium \
chromium-driver \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . /app
WORKDIR /app
CMD ["xvfb-run", "--auto-servernum", "python", "main.py"]
Ajustes de configuração do navegador em modo headless (Node.js)
Reduzir a frequência do CAPTCHA também ajuda, mesmo com a CaptchaAI resolvendo o que sobrar:
const puppeteer = require("puppeteer-extra");
const QaPlugin = require("configuração padrão do Puppeteer");
puppeteer.use(QaPlugin());
async function headlessStealth() {
const browser = await puppeteer.launch({
headless: "new",
args: [
"--no-sandbox",
"--window-size=1920,1080",
"--disable-blink-features=AutomationControlled",
],
});
const page = await browser.newPage();
await page.setViewport({ width: 1920, height: 1080 });
// Additional QA de navegador patches
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, "webdriver", {
get: () => undefined,
});
Object.defineProperty(navigator, "plugins", {
get: () => [1, 2, 3, 4, 5],
});
});
await page.goto("https://example.com/form");
// Detect and solve CAPTCHA with CaptchaAI
const sitekey = await page.evaluate(() =>
document.querySelector("[data-sitekey]")?.getAttribute("data-sitekey")
);
if (sitekey) {
// Call CaptchaAI API (see other guides for full implementation)
const token = await solveCaptchaAI(page.url(), sitekey);
await page.evaluate((t) => {
document.querySelector("#g-recaptcha-response").value = t;
}, token);
}
await browser.close();
}
Benchmarks de desempenho: headless x headed x headed + Xvfb
| Cenário | Headless | Headed | Headed + Xvfb |
|---|---|---|---|
| Tempo de inicialização | ~1 s | ~2 s | ~2,5 s |
| Memória por aba | 100–200 MB | 300–500 MB | 300–500 MB |
| Carregamento de página (média) | 1,5 s | 2,5 s | 2,5 s |
| Pontuação reCAPTCHA v3 | 0,1–0,3 | 0,7–0,9 | 0,5–0,8 |
| Máximo simultâneo (8 GB) | 30–40 | 10–15 | 10–15 |
| Taxa de resolução de CAPTCHA | Igual (API) | Igual (API) | Igual (API) |
A taxa de resolução da CaptchaAI não muda com o modo do navegador. O modo só influencia a frequência com que o CAPTCHA aparece e a pontuação do reCAPTCHA v3 — meça os dois cenários no seu próprio volume antes de decidir.
Erros comuns e como corrigir
- Modo headless detectado — causa: sinalizador
webdriverexposto pelo navegador. Correção: ajuste os sinais do navegador ou aplique patches via CDP. - Pontuação v3 baixa em headless — causa: faltam sinais de renderização. Correção: migre para headed + Xvfb.
- Xvfb trava ao iniciar — causa: conflito de número de display. Correção: use
--auto-servernum. - Memória alta em headed — causa: processo de GPU ativo. Correção: adicione a flag
--disable-gpu. - Screenshot em branco no headless — causa: viewport mal configurado. Correção: defina
--window-size=1920,1080.
Perguntas frequentes
- O modo do navegador muda a taxa de resolução da CaptchaAI? Não. A resolução acontece no servidor via sitekey e URL — o modo só muda a frequência com que o desafio aparece.
- Preciso do Xvfb se já uso a CaptchaAI? Só se o site bloquear sessões headless ou se a pontuação v3 precisar ficar alta. Na maioria dos fluxos, headless com a CaptchaAI já basta.
- Headless é sempre mais barato que headed? Em infraestrutura, sim — mas se ele faz o CAPTCHA aparecer mais, compare o custo total no seu volume real.
- Como sei se o CAPTCHA aparece por causa do headless? Rode a mesma sessão em headed e compare a frequência e a pontuação v3.
- O
--headless=newresolve sozinho a detecção? Não. O sinalizadorwebdrivere a ausência de plugins seguem expostos.
Guias relacionados
- Sinais do navegador e o CAPTCHA
- Ajustes de navegador no Puppeteer com CaptchaAI
- Chrome DevTools Protocol com CaptchaAI
Escolha o modo certo para o seu fluxo de automação — gere sua chave de API da CaptchaAI e resolva CAPTCHA em qualquer configuração de navegador.