Com o modo headless do Chrome, é possível executar o navegador em um ambiente desacompanhado, sem interface visível. Basicamente, é possível executar o Chrome sem o Chrome.
O modo headless é uma escolha comum para automação de navegadores, por meio de projetos como o Puppeteer ou o ChromeDriver.
Usar o modo headless
Para usar o modo sem cabeça, transmita a flag de linha de comando --headless
:
chrome --headless
Usar o modo headless antigo
Anteriormente, o modo headless era
uma implementação separada e alternativa do navegador
que foi enviada como parte do mesmo binário do Chrome. Ele não compartilha
nenhum código do navegador Chrome em
//chrome
.
O Chrome agora tem modos unificados de headless e headful.
Por enquanto, o antigo modo Headless ainda está disponível com:
chrome --headless=old
No Puppeteer
Para usar o modo headless no Puppeteer:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({
headless: 'true', // (default) enables Headless
// `headless: 'old'` enables old Headless
// `headless: false` enables "headful" mode
});
const page = await browser.newPage();
await page.goto('https://developer.chrome.com/');
// …
await browser.close();
No Selenium-WebDriver
Para usar o modo headless no Selenium-WebDriver:
const driver = await env
.builder()
.setChromeOptions(options.addArguments('--headless'))
.build();
await driver.get('https://developer.chrome.com/');
// …
await driver.quit();
Consulte a postagem do blog da equipe do Selenium para mais informações, incluindo exemplos que usam outras vinculações de linguagem.
Sinalizações de linha de comando
As flags de linha de comando a seguir estão disponíveis no modo sem cabeça.
--dump-dom
A sinalização --dump-dom
imprime o DOM serializado da página de destino na stdout.
Exemplo:
chrome --headless --dump-dom https://developer.chrome.com/
Isso é diferente de imprimir o código-fonte HTML, o que pode ser feito com
curl
. Para gerar a saída de --dump-dom
, o Chrome primeiro analisa o código
HTML em um DOM, executa qualquer <script>
que possa alterar o DOM e, em seguida,
transforma esse DOM em uma string serializada de HTML.
--screenshot
A flag --screenshot
faz uma captura de tela da página de destino e a salva como
screenshot.png
no diretório de trabalho atual. Isso é especialmente útil em
combinação com a flag --window-size
.
Exemplo:
chrome --headless --screenshot --window-size=412,892 https://developer.chrome.com/
--print-to-pdf
A flag --print-to-pdf
salva a página de destino como um PDF chamado output.pdf
no
diretório de trabalho atual. Exemplo:
chrome --headless --print-to-pdf https://developer.chrome.com/
Opcionalmente, é possível adicionar a flag --no-pdf-header-footer
para omitir o cabeçalho
de impressão (com a data e a hora atuais) e o rodapé (com o URL e o número
da página).
chrome --headless --print-to-pdf --no-pdf-header-footer https://developer.chrome.com/
Não: a funcionalidade por trás da flag --no-pdf-header-footer
já estava
disponível com a flag --print-to-pdf-no-header
. Talvez seja necessário usar o nome da flag antiga, se você estiver usando uma versão anterior.
--timeout
A flag --timeout
define o tempo máximo de espera (em milissegundos) após o qual
o conteúdo da página é capturado por --dump-dom
, --screenshot
e
--print-to-pdf
, mesmo que a página ainda esteja carregando.
chrome --headless --print-to-pdf --timeout=5000 https://developer.chrome.com/
A flag --timeout=5000
informa ao Chrome para aguardar até 5 segundos antes de imprimir
o PDF. Assim, esse processo leva no máximo 5 segundos para ser executado.
--virtual-time-budget
O --virtual-time-budget
funciona como um "avanço rápido" para qualquer código dependente de tempo
(por exemplo, setTimeout
/setInterval
). Ele força o navegador a executar qualquer
código da página o mais rápido possível, fazendo com que a página acredite que o
tempo realmente passa.
Para ilustrar o uso, considere esta demonstração, que
incrementa, registra e exibe um contador a cada segundo
usando setTimeout(fn, 1000)
. Confira o código relevante:
<output>0</output>
<script>
const element = document.querySelector('output');
let counter = 0;
setInterval(() => {
counter++;
console.log(counter);
element.textContent = counter;
}, 1_000);
</script>
Após um segundo, a página contém "1"; após dois segundos, "2" e assim por diante. Confira como capturar o estado da página após 42 segundos e salvar como PDF:
chrome --headless --print-to-pdf --virtual-time-budget=42000 https://mathiasbynens.be/demo/time
--allow-chrome-scheme-url
A flag --allow-chrome-scheme-url
é necessária para acessar URLs chrome://
.
Essa flag está disponível no Chrome 123. Veja um exemplo:
chrome --headless --print-to-pdf --allow-chrome-scheme-url chrome://gpu
Depurar
Como o Chrome fica invisível no modo Headless, pode parecer difícil resolver um problema. É possível depurar o Headless Chrome de uma forma muito semelhante ao Chrome com cabeça.
Inicie o Chrome no modo headless com a
flag de linha de comando --remote-debugging-port
.
chrome --headless --remote-debugging-port=0 https://developer.chrome.com/
Isso imprime um URL WebSocket exclusivo no stdout, por exemplo:
DevTools listening on ws://127.0.0.1:60926/devtools/browser/b4bd6eaa-b7c8-4319-8212-225097472fd9
Em uma instância headful do Chrome, podemos usar a depuração remota do Chrome DevTools (link em inglês) para se conectar ao destino headless e inspecioná-lo.
- Acesse
chrome://inspect
e clique no botão Configurar. - Insira o endereço IP e o número da porta do URL do WebSocket.
- No exemplo anterior, digitei
127.0.0.1:60926
.
- No exemplo anterior, digitei
- Clique em Concluído. Um destino remoto vai aparecer com todas as guias e outros destinos listados.
- Clique em inspecionar para acessar o Chrome DevTools e inspecionar o destino sem comando remoto, incluindo uma imagem ao vivo da página.
Feedback
Aguardamos seu feedback sobre o modo sem cabeça. Se você encontrar algum problema, informe um bug.