Modalità headless di Chrome

Peter Kvitek
Peter Kvitek

Con la modalità headless di Chrome, puoi eseguire il browser in un ambiente automatico, senza alcuna UI visibile. In sostanza, puoi eseguire Chrome senza Chrome.

La modalità headless è una scelta popolare per l'automazione del browser, tramite progetti come Puppeteer o ChromeDriver.

Utilizzare la modalità headless

Per utilizzare la modalità headless, passa il flag della riga di comando --headless:

chrome --headless

Utilizzare la modalità headless precedente

In precedenza, la modalità Headless era un'implementazione del browser separata e alternativa che veniva spedita come parte dello stesso binario di Chrome. Non ha condiviso alcun codice del browser Chrome in //chrome.

Ora Chrome ha modalità headless e headful unificate.

La modalità headless condivide il codice con Chrome.

A partire da Chrome 132.0.6793.0, la vecchia modalità headless è disponibile solo come file binario autonomo denominato chrome-headless-shell, che può essere scaricato qui.

In Puppeteer

Per utilizzare la modalità headless in Puppeteer:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({
  headless: true,  // (default) enables Chrome Headless mode
  // `headless: 'shell'` enables Headless Shell (old headless)
  // `headless: false` enables "headful" mode
});

const page = await browser.newPage();
await page.goto('https://developer.chrome.com/');

// …

await browser.close();

Per saperne di più sull'utilizzo di Headless in Puppeteer, puoi consultare le risorse disponibili qui.

In Selenium-WebDriver

Per utilizzare la modalità headless in Selenium-WebDriver:

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

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

// …

await driver.quit();

Per ulteriori informazioni, inclusi esempi di utilizzo di altri binding di linguaggio, consulta il post del blog del team di Selenium.

Flag della riga di comando

I seguenti flag della riga di comando sono disponibili in modalità Headless e in Headless Shell.

--dump-dom

Il flag --dump-dom stampa il DOM serializzato della pagina di destinazione su stdout. Ad esempio:

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

Questa operazione è diversa dalla stampa del codice sorgente HTML, che potresti eseguire con curl. Per fornirti l'output di --dump-dom, Chrome analizza prima il codice HTML in un DOM, esegue qualsiasi <script> che potrebbe alterare il DOM, quindi trasforma di nuovo il DOM in una stringa serializzata di HTML.

--screenshot

Il flag --screenshot acquisisce uno screenshot della pagina di destinazione e lo salva come screenshot.png nella directory di lavoro corrente. Ciò è particolarmente utile in combinazione con il flag --window-size.

Ad esempio:

chrome --headless --screenshot --window-size=412,892 https://developer.chrome.com/

--print-to-pdf

Il flag --print-to-pdf salva la pagina di destinazione come PDF denominato output.pdf nella directory di lavoro corrente. Ad esempio:

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

(Facoltativo) Puoi aggiungere il flag --no-pdf-header-footer per omettere l'intestazione (con data e ora correnti) e il piè di pagina (con l'URL e il numero di pagina) della stampa.

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

Nota: la funzionalità alla base del flag --no-pdf-header-footer era precedentemente disponibile con il flag --print-to-pdf-no-header. Se utilizzi una versione precedente, potresti dover ripristinare il vecchio nome del flag.

--timeout

Il flag --timeout definisce il tempo di attesa massimo (in millisecondi) dopo il quale i contenuti della pagina vengono acquisiti da --dump-dom, --screenshot e --print-to-pdf anche se la pagina è ancora in fase di caricamento.

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

Il flag --timeout=5000 indica a Chrome di attendere fino a 5 secondi prima di stampare il PDF. Pertanto, l'esecuzione di questo processo richiede al massimo 5 secondi.

--virtual-time-budget

--virtual-time-budget funge da "avanzamento rapido" per qualsiasi codice dipendente dal tempo (ad esempio, setTimeout/setInterval). Forza il browser a eseguire qualsiasi codice della pagina il più rapidamente possibile, facendo credere alla pagina che il tempo passi effettivamente.

Per illustrarne l'utilizzo, considera questa demo, che incrementa, registra e visualizza un contatore ogni secondo utilizzando setTimeout(fn, 1000). Ecco il codice pertinente:

<output>0</output>
<script>
  const element = document.querySelector('output');
  let counter = 0;
  setInterval(() => {
    counter++;
    console.log(counter);
    element.textContent = counter;
  }, 1_000);
</script>

Dopo un secondo, la pagina contiene "1"; dopo due secondi, "2" e così via. Ecco come acquisire lo stato della pagina dopo 42 secondi e salvarlo come PDF:

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

--allow-chrome-scheme-url

Il flag --allow-chrome-scheme-url è necessario per accedere agli URL chrome://. Questo flag è disponibile a partire da Chrome 123. Ecco un esempio:

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

Debug

Poiché Chrome è effettivamente invisibile in modalità Headless, potrebbe sembrare difficile risolvere un problema. È possibile eseguire il debug di Headless Chrome in modo molto simile a Chrome con interfaccia grafica.

Avvia Chrome in modalità Headless con il flag della riga di comando --remote-debugging-port.

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

Viene stampato un URL WebSocket univoco su stdout, ad esempio:

DevTools listening on ws://127.0.0.1:60926/devtools/browser/b4bd6eaa-b7c8-4319-8212-225097472fd9

In un'istanza di Chrome con interfaccia grafica, possiamo quindi utilizzare il debug remoto di Chrome DevTools per connetterci alla destinazione headless ed esaminarla.

  1. Vai a chrome://inspect e fai clic sul pulsante Configura….
  2. Inserisci l'indirizzo IP e il numero di porta dell'URL WebSocket.
    • Nell'esempio precedente, ho inserito 127.0.0.1:60926.
  3. Fai clic su Fine. Dovresti visualizzare un target remoto con tutte le relative schede e gli altri target elencati.
  4. Fai clic su Ispeziona per accedere a Chrome DevTools e ispezionare la destinazione headless remota, inclusa una visualizzazione live della pagina.

Chrome DevTools può ispezionare una pagina di destinazione headless remota

Feedback

Non vediamo l'ora di ricevere il tuo feedback sulla modalità Headless. Se riscontri problemi, segnala un bug.