Eventos e depuração
Quais eventos da página chegam ao seu cliente de automação, como capturar a saída do console mesmo assim e como conferir qual renderizador realmente pinta a página.
Eventos de console e de erro de página
O motor não repassa eventos de console nem de erro de página para clientes de automação, então page.on("console") e page.on("pageerror") não recebem nada. Isso é intencional — repassá-los é exatamente o que uma sonda de presença de automação mede. Os handlers window.onerror e unhandledrejection dentro da página disparam normalmente; então, para capturar a saída do console, colete-a na própria página e leia de volta com page.evaluate(). Os SDKs de Python e Node exibem um aviso sobre isso, uma única vez, na inicialização.
Duas chamadas do driver dependem desses eventos. O page.setContent() do Playwright espera por um evento de console, então dá timeout (o do Puppeteer funciona): abra o HTML como uma URL data: ou escreva-o na página com page.evaluate(). O exposeFunction() e o exposeBinding(), no Playwright e no Puppeteer, funcionam na página que está aberta quando você os chama e somem assim que essa página navega: chame-os depois da última navegação ou devolva os resultados pelo page.evaluate().
from urllib.parse import quote
# Instead of page.set_content(html):
# short HTML: a data: URL (the page gets no origin of its own, so no cookies or storage)
page.goto("data:text/html," + quote(html))
# any HTML: write it into a page you have navigated to; it keeps that page's origin
page.evaluate("html => { document.open(); document.write(html); document.close(); }", html)Verificação de coerência do backend de renderização (checkRenderCoherence)
Uma persona pode declarar uma GPU, mas, se a página for de fato pintada por um rasterizador de software (SwiftShader / llvmpipe — comum em headless sem GPU), um detector rigoroso consegue perceber. Verifique uma página carregada: a função lê o vendor/renderer do WebGL (sem máscara) que a página realmente vê, sinaliza um fallback para rasterizador de software (um indício fatal de headless — ative a canvas bridge ou rode em modo headed numa GPU real) ou um par vendor/renderer incoerente, e devolve um veredito estruturado. Passe a GPU declarada para conferir também a família renderizada. Disponível em versão síncrona, assíncrona e em Node.
from clearcote import launch, check_render_coherence
browser = launch(fingerprint="seed-123")
page = browser.new_page(); page.goto("about:blank")
verdict = check_render_coherence(page) # {'renderer', 'software_suspected', 'coherent', 'warnings'}
if not verdict["coherent"]:
print(verdict["warnings"]) # e.g. software rasterizer / incoherent GPU family
browser.close()