Der monitorlose Modus von Chrome erhält ein Upgrade: --headless=new

Der Headless-Modus von Chrome ist jetzt noch besser!

Peter Kvitek
Peter Kvitek

Der Headless-Modus von Chrome ist jetzt noch besser! In diesem Artikel erhalten Sie einen Überblick über die jüngsten technischen Bemühungen, die Funktion „Headless“ für Entwickler noch hilfreicher zu machen. Dazu wird die Funktion „Headless“ näher an den regulären „Headful-Modus“ von Chrome herangeführt.

Hintergrund

Im Jahr 2017 wurde in Chrome 59 der sogenannte monitorlose Modus eingeführt, mit dem Sie den Browser in einer unbeaufsichtigten Umgebung ohne sichtbare Benutzeroberfläche ausführen können. Chrome ohne Chrome ausführen

Der monitorlose Modus ist eine beliebte Wahl für die Browserautomatisierung mit Projekten wie Puppeteer oder ChromeDriver. Hier ist ein minimales Befehlszeilenbeispiel für die Verwendung des monitorlosen Modus, um eine PDF-Datei einer bestimmten URL zu erstellen:

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

Neues bei „Headless“

Bevor wir uns die neuesten Verbesserungen von Headless ansehen, möchten wir wissen, wie das „alte“ Headless-Modell funktioniert hat. Im Befehlszeilen-Snippet, das wir zuvor gezeigt haben, wird das Befehlszeilen-Flag --headless verwendet, was darauf hindeutet, dass die Funktion „Headless“ nur ein Betriebsmodus des regulären Chrome-Browsers ist. Überraschenderweise stimmte das nicht. Technisch gesehen war das alte Headless-Modell eine separate, alternative Browserimplementierung, die zufällig als Teil des Chrome-Binärprogramms ausgeliefert wurde. Der Code des Chrome-Browsers in //chrome wird nicht weitergegeben.

Wie Sie sich vielleicht vorstellen können, war die Implementierung und Wartung dieses separaten monitorlosen Browsers mit einem hohen Engineering-Aufwand verbunden – aber das war nicht das einzige Problem. Da Headless eine separate Implementierung war, gab es einige Fehler und Funktionen, die in der Headful Chrome nicht vorhanden waren. Dies führte zu einer verwirrenden Situation, in der jeder automatisierte Browsertest im Headful-Modus erfolgreich war, aber im monitorlosen Modus fehlschlägt oder umgekehrt. Automatisierte Tests ausgeschlossen, die beispielsweise die Installation einer Browsererweiterung erforderten. Dasselbe gilt für alle anderen Funktionen auf Browserebene: Wenn Headless keine eigene, separate Implementierung hatte, wurde es nicht unterstützt.

2021 machte sich das Chrome-Team daran, dieses Problem zu lösen und den Headless- und den Headful-Modus ein für alle Mal zu vereinheitlichen.

Die neue Headless-Version von Chrome ist keine separate Browserimplementierung mehr. Stattdessen teilt sie Code mit Chrome.

Wir freuen uns, dir mitteilen zu können, dass der neue monitorlose Modus jetzt in Chrome 112 verfügbar ist. In diesem Modus erstellt Chrome Plattformfenster, zeigt diese aber nicht an. Alle anderen bestehenden und zukünftigen Funktionen sind ohne Einschränkungen verfügbar.

Das neue Headless-Design ausprobieren

Übergeben Sie das Befehlszeilen-Flag --headless=new, um den neuen monitorlosen Modus auszuprobieren:

chrome --headless=new

Vorerst ist der alte monitorlose Modus weiterhin verfügbar über:

chrome --headless=old

Derzeit wird der alte monitorlose Modus aktiviert, wenn das Befehlszeilen-Flag --headless ohne einen expliziten Wert übergeben wird. Wir planen jedoch, diese Standardeinstellung im Laufe der Zeit in die neue Option „Headless“ zu ändern.

Wir planen, die alte Headless-Version aus dem Chrome-Binärprogramm zu entfernen und diesen Modus im Laufe des Jahres in Puppeteer nicht mehr zu unterstützen. Im Rahmen dieser Neuerung stellen wir das alte Headless-Programm als separates eigenständiges Binärprogramm für Nutzer zur Verfügung, die noch kein Upgrade durchführen können.

Neu in Puppeteer: Headless

So aktivieren Sie den neuen monitorlosen Modus in 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();

Neu: Headless in Selenium-WebDriver

So verwenden Sie den neuen monitorlosen Modus in Selenium-WebDriver:

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

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

// …

await driver.quit();

Weitere Informationen und Beispiele für andere Sprachbindungen finden Sie im Blogpost des Selenium-Teams.

Monitorlose Befehlszeilen-Flags

Die folgenden Befehlszeilen-Flags sind für den neuen monitorlosen Modus verfügbar.

--dump-dom

Das Flag --dump-dom gibt das serielle DOM der Zielseite in stdout aus. Beispiel:

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

Beachten Sie, dass sich dies vom einfachen Drucken des HTML-Quellcodes wie mit curl unterscheidet. Damit Sie die Ausgabe von --dump-dom erhalten, parst Chrome zuerst den HTML-Code in ein DOM, führt jede <script> aus, die das DOM ändern könnte, und wandelt dieses DOM dann wieder in einen seriellen HTML-String um.

--screenshot

Mit dem Flag --screenshot wird ein Screenshot der Landingpage erstellt und als screenshot.png im aktuellen Arbeitsverzeichnis gespeichert. Das ist besonders in Kombination mit dem Flag --window-size nützlich. Beispiel:

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

--print-to-pdf

Das Flag --print-to-pdf speichert die Zielseite als PDF-Datei mit dem Namen output.pdf im aktuellen Arbeitsverzeichnis. Beispiel:

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

Optional können Sie das Flag --no-pdf-header-footer hinzufügen, um die gedruckte Kopfzeile (mit dem aktuellen Datum und die Uhrzeit) und die Fußzeile (mit URL und Seitennummer) wegzulassen.

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

--timeout

Das Flag --timeout definiert die maximale Wartezeit (in Millisekunden), nach der der Inhalt der Seite von --dump-dom, --screenshot und --print-to-pdf erfasst wird, auch wenn die Seite noch geladen wird.

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

Das Flag --timeout=5000 weist Chrome an, bis zu 5 Sekunden zu warten, bevor die PDF-Datei gedruckt wird. Dieser Prozess dauert also maximal 5 Sekunden.

--virtual-time-budget

Die --virtual-time-budget ermöglicht eine Zeitreise! Nun, zu einem gewissen Grad. Virtuelle Zeit fungiert als „Vorspulen“ für jeglichen zeitabhängigen Code (z. B. setTimeout/setInterval). Sie zwingt den Browser dazu, Code der Seite so schnell wie möglich auszuführen, während auf der Seite angenommen wird, dass die Zeit tatsächlich verstreicht.

Die Verwendung wird auf dieser Demoseite veranschaulicht, auf der mit setTimeout(fn, 1000) ein Zähler pro Sekunde erhöht, protokolliert und angezeigt wird. Hier ist der entsprechende Code:

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

Nach einer Sekunde enthält die Seite „1“; nach zwei Sekunden „2“ und so weiter. So würden Sie den Status der Seite nach 42 Sekunden erfassen und als PDF speichern:

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

--allow-chrome-scheme-url

Das Flag --allow-chrome-scheme-url ist für den Zugriff auf chrome://-URLs erforderlich. Dieses Flag ist ab Chrome 123 verfügbar. Beispiel:

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

Debugging

Da Chrome im monitorlosen Modus praktisch nicht sichtbar ist, ist es möglicherweise schwierig, herauszufinden, woran das liegt, wenn Probleme auftreten. Die Fehlerbehebung von Headless Chrome funktioniert ähnlich wie bei Headful Chrome. Der Trick besteht darin, Chrome mit dem Befehlszeilen-Flag --remote-debugging-port im monitorlosen Modus zu starten.

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

Dadurch wird eine eindeutige WebSocket-URL für stdout ausgegeben. Beispiel:

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

In einer normalen Headful-Chrome-Instanz können wir dann mithilfe der Chrome-Entwicklertools-Remote-Debugging eine Verbindung zum monitorlosen Ziel herstellen und das Ziel untersuchen. Gehen Sie dazu zu chrome://inspect, klicken Sie auf die Schaltfläche Konfigurieren... und geben Sie die IP-Adresse und Portnummer aus der WebSocket-URL ein. Im obigen Beispiel habe ich 127.0.0.1:60926 eingegeben. Klicken Sie auf Fertig. Nun sollten Sie ein Remote-Ziel mit allen Tabs und anderen Zielen unten sehen. Wenn Sie auf inspect klicken, haben Sie jetzt Zugriff auf die Chrome-Entwicklertools. Mit diesen können Sie das monitorlose Remote-Ziel prüfen, inspect.

Chrome-Entwicklertools können eine monitorlose Remote-Landingpage prüfen

Feedback

Wir freuen uns auf Ihr Feedback zum neuen monitorlosen Modus. Falls Probleme auftreten, melden Sie uns diese bitte.