Mode headless de Chrome

Mathias Bynens
Mathias Bynens
Peter Kvitek
Peter Kvitek

En 2017, Chrome 59 a introduit le mode headless, qui vous permet d'exécuter le navigateur dans un environnement sans assistance, sans interface utilisateur visible. En bref, vous pouvez exécuter Chrome sans Chrome.

Le mode headless est un choix populaire pour l'automatisation des navigateurs, par le biais de projets tels que Puppeteer ou ChromeDriver. Voici un exemple de ligne de commande minimal utilisant le mode headless pour créer un fichier PDF d'une URL donnée:

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

Comment fonctionne le mode headless ?

Avant d'examiner le fonctionnement de "Headless", il est important de comprendre son fonctionnement. L'extrait de ligne de commande précédent utilise l'indicateur de ligne de commande --headless, suggérant que l'option "Headless" n'est qu'un mode de fonctionnement du navigateur Chrome standard. Étonnamment, ce n'était peut-être pas vrai. En fait, l'ancienne interface headless était une implémentation alternative et distincte du navigateur qui était envoyée dans le même binaire Chrome. Il ne partage aucun code du navigateur Chrome dans //chrome.

La mise en œuvre et la maintenance d'un navigateur headless distinct entraînaient de nombreux coûts d'ingénierie. Comme headless était une implémentation distincte, elle avait ses propres bugs et fonctionnalités qui n'étaient pas présentes dans Headful Chrome. Cela créait une confusion pour les tests automatisés du navigateur, qui peuvent réussir en mode headful, mais échouer en mode headless, ou inversement.

De plus, Headless a exclu tout test automatisé basé sur l'installation d'extensions de navigateur. Il en va de même pour toutes les autres fonctions au niveau du navigateur. À moins d'utiliser une implémentation sans interface graphique distincte, celle-ci n'était pas compatible.

L'équipe Chrome a désormais unifié les modes headless et headless.

La nouvelle version de Chrome Headless n'est plus une implémentation distincte du navigateur, mais partage désormais le code avec Chrome.

Le nouveau mode headless est disponible dans Chrome 112. Dans ce mode, Chrome crée, mais n'affiche aucune fenêtre de plate-forme. Toutes les autres fonctions, existantes et futures, sont disponibles sans limitation.

Utiliser le mode headless

Pour utiliser le nouveau mode headless, transmettez l'indicateur de ligne de commande --headless=new:

chrome --headless=new

Pour l'instant, l'ancien mode headless est toujours disponible avec:

chrome --headless=old

Dans Puppeteer

Pour activer le nouveau mode headless dans 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();

Dans Selenium-WebDriver

Pour utiliser le nouveau mode headless dans Selenium-WebDriver:

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

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

// …

await driver.quit();

Consultez l'article de blog de l'équipe Selenium pour en savoir plus, y compris pour découvrir des exemples utilisant des liaisons d'autres langages.

Options de ligne de commande

Les options de ligne de commande suivantes sont disponibles dans le nouveau mode headless.

--dump-dom

L'option --dump-dom imprime le DOM sérialisé de la page cible sur stdout. Exemple :

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

Cette opération est différente de l'impression du code source HTML, ce que vous pouvez faire avec curl. Pour vous fournir la sortie de --dump-dom, Chrome analyse d'abord le code HTML dans un DOM, exécute toutes les <script> susceptibles de modifier le DOM, puis le transforme en chaîne HTML sérialisée.

--screenshot

L'option --screenshot effectue une capture d'écran de la page cible et l'enregistre sous le nom screenshot.png dans le répertoire de travail actuel. Cela est particulièrement utile lorsqu'il est combiné avec l'indicateur --window-size.

Exemple :

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

--print-to-pdf

L'indicateur --print-to-pdf enregistre la page cible au format PDF nommé output.pdf dans le répertoire de travail actuel. Exemple :

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

Vous pouvez éventuellement ajouter l'option --no-pdf-header-footer pour omettre l'en-tête d'impression (avec la date et l'heure actuelles) et le pied de page (avec l'URL et le numéro de page).

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

Non: la fonctionnalité derrière l'indicateur --no-pdf-header-footer était auparavant disponible avec l'option --print-to-pdf-no-header. Si vous utilisez une version antérieure, vous devrez peut-être revenir à l'ancien nom.

--timeout

L'indicateur --timeout définit le temps d'attente maximal (en millisecondes) au terme duquel le contenu de la page est capturé par --dump-dom, --screenshot et --print-to-pdf, même si la page est toujours en cours de chargement.

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

L'indicateur --timeout=5000 indique à Chrome d'attendre jusqu'à cinq secondes avant d'imprimer le PDF. L'exécution de ce processus prend donc au maximum 5 secondes.

--virtual-time-budget

--virtual-time-budget agit comme une "avance rapide" pour tout code dépendant de l'heure (par exemple, setTimeout/setInterval). Il oblige le navigateur à exécuter n'importe quel code de la page aussi rapidement que possible tout en laissant à la page croire que le temps passe réellement.

Pour illustrer son utilisation, prenons l'exemple de cette démonstration, qui incrémente, consigne et affiche un compteur toutes les secondes à l'aide de setTimeout(fn, 1000). Voici le code approprié:

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

Au bout d'une seconde, la page contient "1", "2" après deux secondes, et ainsi de suite. Pour capturer l'état de la page au bout de 42 secondes et l'enregistrer au format PDF, procédez comme suit:

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

--allow-chrome-scheme-url

L'indicateur --allow-chrome-scheme-url est requis pour accéder aux URL chrome://. Cet indicateur est disponible à partir de Chrome 123. Exemple :

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

Déboguer

Étant donné que Chrome est en réalité invisible en mode headless, il peut sembler difficile de résoudre un problème. Il est possible de déboguer Chrome headless d'une manière très semblable à celle de Chrome headful.

Lancez Chrome en mode headless avec l'indicateur de ligne de commande --remote-debugging-port.

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

Cette commande imprime une URL WebSocket unique vers stdout, par exemple:

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

Dans une instance Chrome tête-à-tête, nous pouvons ensuite utiliser le débogage à distance des outils pour les développeurs Chrome pour nous connecter à la cible headless et l'inspecter.

  1. Accédez à chrome://inspect et cliquez sur le bouton Configure (Configurer).
  2. Saisissez l'adresse IP et le numéro de port issus de l'URL WebSocket.
    • Dans l'exemple précédent, j'ai saisi 127.0.0.1:60926.
  3. Cliquez sur OK. Une cible distante doit s'afficher avec tous ses onglets et autres cibles répertoriés.
  4. Cliquez sur Inspecter pour accéder aux outils pour les développeurs Chrome et inspecter la cible headless distante, y compris une vue en direct de la page.

Les outils pour les développeurs Chrome peuvent inspecter une page cible headless distante

Commentaires

Nous sommes impatients de recevoir vos commentaires sur le nouveau mode headless. Si vous rencontrez des problèmes, signalez un bug.