Chrome Headless-modus

Peter Kvitek
Peter Kvitek

In 2017 introduceerde Chrome 59 de Headless-modus , waarmee u de browser in een onbeheerde omgeving kunt uitvoeren, zonder enige zichtbare gebruikersinterface. In wezen zou u Chrome zonder chroom kunnen gebruiken.

De headless-modus is een populaire keuze voor browserautomatisering, via projecten als Puppeteer of ChromeDriver . Hier is een minimaal opdrachtregelvoorbeeld waarin de Headless-modus wordt gebruikt om een ​​PDF-bestand van een bepaalde URL te maken:

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

Hoe werkt Hoofdloos?

Voordat we bekijken hoe Headless nu werkt, is het belangrijk om te begrijpen hoe de "oude" Headless werkte. Het vorige opdrachtregelfragment gebruikt de opdrachtregelvlag --headless , wat suggereert dat Headless slechts een bedieningsmodus is van de gewone Chrome-browser. Misschien verrassend genoeg was dit eigenlijk niet waar. In feite was de oude Headless een afzonderlijke, alternatieve browserimplementatie die toevallig werd geleverd als onderdeel van hetzelfde Chrome-binaire bestand. Het deelt geen enkele Chrome-browsercode in //chrome .

Het implementeren en onderhouden van een aparte Headless-browser bracht veel technische overhead met zich mee. En omdat Headless een afzonderlijke implementatie was, had het zijn eigen bugs en functies die niet aanwezig waren in Headful Chrome. Dit zorgde voor verwarring bij geautomatiseerde browsertests, die in de headful-modus zouden kunnen slagen, maar mislukken in de Headless-modus, of omgekeerd.

Verder sloot Headless alle geautomatiseerde tests uit die afhankelijk waren van de installatie van browserextensies. Hetzelfde geldt voor alle andere functies op browserniveau; tenzij Headless er een eigen, afzonderlijke implementatie van had, werd het niet ondersteund.

Het Chrome-team heeft nu de Headless- en Headful-modi verenigd.

De nieuwe Chrome Headless is niet langer een aparte browserimplementatie, maar deelt nu code met Chrome.

De nieuwe Headless-modus is beschikbaar vanaf Chrome 112. In deze modus maakt Chrome platformvensters, maar geeft deze niet weer. Alle andere functies, bestaande en toekomstige, zijn zonder beperkingen beschikbaar.

Gebruik de Headless-modus

Om de nieuwe Headless-modus te gebruiken, geeft u de opdrachtregelvlag --headless=new door:

chrome --headless=new

Voorlopig is de oude Headless-modus nog steeds beschikbaar met:

chrome --headless=old

In Poppenspeler

Om je aan te melden voor de nieuwe Headless-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();

In Selenium-WebDriver

Om de nieuwe Headless-modus in Selenium-WebDriver te gebruiken:

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

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

// …

await driver.quit();

Zie de blogpost van het Selenium-team voor meer informatie, inclusief voorbeelden van het gebruik van andere taalbindingen.

Commandoregelvlaggen

De volgende opdrachtregelvlaggen zijn beschikbaar in de nieuwe Headless-modus.

--dump-dom

De vlag --dump-dom drukt de geserialiseerde DOM van de doelpagina af naar stdout. Bijvoorbeeld:

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

Dit is anders dan het afdrukken van de HTML-broncode, wat u zou kunnen doen met curl . Om u de uitvoer van --dump-dom te geven, parseert Chrome eerst de HTML-code in een DOM, voert een <script> uit dat de DOM zou kunnen veranderen en verandert die DOM vervolgens weer in een geserialiseerde HTML-reeks.

--screenshot

De vlag --screenshot maakt een screenshot van de doelpagina en slaat deze op als screenshot.png in de huidige werkmap. Dit is vooral handig in combinatie met de vlag --window-size .

Bijvoorbeeld:

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

--print-to-pdf

De vlag --print-to-pdf slaat de doelpagina op als een PDF met de naam output.pdf in de huidige werkmap. Bijvoorbeeld:

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

Optioneel kunt u de vlag --no-pdf-header-footer toevoegen om de printkoptekst (met de huidige datum en tijd) en voettekst (met de URL en het paginanummer) weg te laten.

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

Niet: de functionaliteit achter de vlag --no-pdf-header-footer was eerder beschikbaar met de vlag --print-to-pdf-no-header . Mogelijk moet u terugvallen op de oude vlagnaam als u een eerdere versie gebruikt.

--timeout

De vlag --timeout definieert de maximale wachttijd (in milliseconden) waarna de inhoud van de pagina wordt vastgelegd door --dump-dom , --screenshot en --print-to-pdf zelfs als de pagina nog wordt geladen.

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

De vlag --timeout=5000 geeft aan dat Chrome maximaal 5 seconden moet wachten voordat de PDF wordt afgedrukt. Dit proces duurt dus maximaal 5 seconden.

--virtual-time-budget

Het --virtual-time-budget fungeert als een "snel vooruitspoelen" voor elke tijdsafhankelijke code (bijvoorbeeld setTimeout / setInterval ). Het dwingt de browser om de code van de pagina zo snel mogelijk uit te voeren, terwijl de pagina denkt dat de tijd daadwerkelijk verstrijkt.

Om het gebruik ervan te illustreren, kunt u deze demo overwegen, waarin elke seconde een teller wordt verhoogd, geregistreerd en weergegeven met behulp van setTimeout(fn, 1000) . Hier is de relevante code:

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

Na één seconde bevat de pagina "1"; na twee seconden, "2", enzovoort. Zo legt u de status van de pagina na 42 seconden vast en slaat u deze op als PDF:

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

--allow-chrome-scheme-url

De vlag --allow-chrome-scheme-url is vereist voor toegang tot chrome:// URL's. Deze vlag is beschikbaar via Chrome 123. Hier is een voorbeeld:

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

Foutopsporing

Omdat Chrome feitelijk onzichtbaar is in de Headless-modus, kan het lastig klinken om een ​​probleem op te lossen. Het is mogelijk om Headless Chrome te debuggen op een manier die sterk lijkt op headful Chrome.

Start Chrome in Headless-modus met de opdrachtregelvlag --remote-debugging-port .

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

Hiermee wordt een unieke WebSocket-URL naar stdout afgedrukt, bijvoorbeeld:

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

In een headful Chrome-exemplaar kunnen we vervolgens Chrome DevTools foutopsporing op afstand gebruiken om verbinding te maken met het Headless-doel en het te inspecteren.

  1. Ga naar chrome://inspect en klik op de knop Configureren… .
  2. Voer het IP-adres en poortnummer van de WebSocket-URL in.
    • In het vorige voorbeeld heb ik 127.0.0.1:60926 ingevoerd.
  3. Klik op Gereed . U zou een extern doel moeten zien verschijnen met alle tabbladen en andere doelen vermeld.
  4. Klik op inspecteren om toegang te krijgen tot Chrome DevTools en inspecteer het externe Headless-doel, inclusief een liveweergave van de pagina.

Chrome DevTools kan een Headless-doelpagina op afstand inspecteren

Feedback

We kijken uit naar uw feedback over de nieuwe Headless-modus. Als u problemen ondervindt, dient u een bug in .