Modo headless do Chrome

Peter Kvitek
Peter Kvitek

Em 2017, o Chrome 59 lançou o modo headless, que permitem executar o navegador em um ambiente autônomo, sem nenhuma interface visível. Basicamente, era possível executar o Chrome sem ele.

O modo headless é uma escolha comum para automação de navegadores, usando projetos como Puppeteer ou ChromeDriver. Este é um exemplo mínimo de linha de comando usando o modo headless para criar um arquivo PDF de um determinado URL:

chrome --headless --print-to-pdf https://developer.chrome.com/

Como o Headless funciona

Antes de conferir como o Headless funciona, é importante entender como o “antigo” A headless funcionou. O snippet de linha de comando anterior usa o --headless , sugerindo que headless é apenas um modo de operação do navegador Chrome normal. Surpreendentemente, isso não é realmente verdade. Na verdade, o antigo Headless era uma implementação separada em navegador alternativo, que foi enviado como parte do mesmo binário do Chrome. Não compartilha o código do navegador Chrome //chrome

Implementar e manter um navegador headless separado trouxe muitos o overhead de engenharia. E, como o Headless era um implementação, ele tinha os próprios bugs e recursos que não estavam presentes no Chrome. Isso criava confusão para os testes automatizados do navegador, o que pode passar mas falha no modo headless ou vice-versa.

Além disso, a headless exclui qualquer teste automatizado que dependia do navegador instalação da extensão. O mesmo vale para outras funções no nível do navegador. a menos que o headless tivesse sua própria implementação separada, ele não teria suporte.

A equipe do Chrome unificou os modos headless e headful.

O novo Chrome Headless não é mais uma implementação de navegador separada e agora compartilha o código com o Chrome.

O novo modo headless está disponível a partir do Chrome 112. Nesse modo, o Chrome cria, mas não exibe nenhuma janela de plataforma. Todas as outras funções, existentes e no futuro, estão disponíveis sem limitações.

Usar o modo headless

Para usar o novo modo headless, transmita a flag de linha de comando --headless=new:

chrome --headless=new

Por enquanto, o antigo modo headless ainda está disponível com:

chrome --headless=old

No Puppeteer

Para ativar o novo modo headless no Puppeteer:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({
  headless: 'new',
  // `headless: true` (default) enables old Headless;
  // `headless: 'new'` enables new 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 novo modo headless no Selenium-WebDriver:

const driver = await env
  .builder()
  .setChromeOptions(options.addArguments('--headless=new'))
  .build();

await driver.get('https://developer.chrome.com/');

// …

await driver.quit();

Consulte a postagem do blog da equipe do Selenium (em inglês) para mais informações, incluindo exemplos que usam outras vinculações de linguagem.

Sinalizações de linha de comando

As sinalizações de linha de comando a seguir estão disponíveis no novo modo headless.

--dump-dom

A sinalização --dump-dom imprime o DOM serializado da página de destino na stdout. Exemplo:

chrome --headless=new --dump-dom https://developer.chrome.com/

Isso é diferente de imprimir o código-fonte HTML, que é possível fazer curl: Para trazer a saída de --dump-dom, o Chrome primeiro analisa o HTML em um DOM, executa qualquer <script> que possa alterar o DOM transforma esse DOM de volta 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 com a sinalização --window-size.

Exemplo:

chrome --headless=new --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 em diretório de trabalho atual. Exemplo:

chrome --headless=new --print-to-pdf https://developer.chrome.com/

Opcionalmente, adicione a flag --no-pdf-header-footer para omitir a exibição cabeçalho (com a data e hora atuais) e rodapé (com o URL e a página número).

chrome --headless=new --print-to-pdf --no-pdf-header-footer https://developer.chrome.com/

Não: a funcionalidade por trás da flag --no-pdf-header-footer era disponível com a flag --print-to-pdf-no-header. Talvez você precise usar o nome da sinalização antiga, se uma versão anterior estiver sendo usada.

--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=new --print-to-pdf --timeout=5000 https://developer.chrome.com/

A flag --timeout=5000 instrui o Chrome a esperar até cinco 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 atua como um "avanço rápido", para qualquer código que depende do horário (por exemplo, setTimeout/setInterval). Ele força o navegador a executar qualquer do código da página o mais rápido possível, ao mesmo tempo que faz a página acreditar que o o tempo realmente passa.

Para ilustrar como usá-lo, 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>

Depois de um segundo, a página contém "1"; depois de dois segundos, "2" e assim por diante. Veja como capturar o estado da página após 42 segundos e salvá-lo como PDF:

chrome --headless=new --print-to-pdf --virtual-time-budget=42000 https://mathiasbynens.be/demo/time

--allow-chrome-scheme-url

A sinalização --allow-chrome-scheme-url é necessária para acessar URLs chrome://. Essa flag está disponível no Chrome 123. Veja um exemplo:

chrome --headless=new --print-to-pdf --allow-chrome-scheme-url chrome://gpu

Depurar

Como o Chrome fica efetivamente invisível no modo headless, pode parecer complicado para resolver um problema. É possível depurar o Headless Chrome de uma maneira semelhante ao headful do Chrome.

Inicie o Chrome no modo headless com as sinalização de linha de comando --remote-debugging-port.

chrome --headless=new --remote-debugging-port=0 https://developer.chrome.com/

Isso imprime um URL WebSocket exclusivo em 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 Depuração remota do Chrome DevTools para conectar ao destino headless e inspecioná-lo.

  1. Acesse chrome://inspect e clique no botão Configure....
  2. Digite o endereço IP e o número da porta do URL do WebSocket.
    • No exemplo anterior, inseri 127.0.0.1:60926.
  3. Clique em Concluído. Um Destino remoto deve aparecer com todas as guias e e outros destinos listados.
  4. Clique em inspecionar para acessar o Chrome DevTools e inspecionar o controle remoto Destino headless, incluindo uma visualização ao vivo da página.

O Chrome DevTools pode inspecionar uma página de destino headless remoto

Feedback

Queremos seu feedback sobre o novo modo headless. Se encontrar problemas, registre um bug.