De Headless-modus van Chrome krijgt een upgrade: introductie van --headless=new

De Headless-modus van Chrome is nu een stuk beter geworden!

Peter Kvitek
Peter Kvitek

De Headless-modus van Chrome is nu een stuk beter geworden! Dit artikel geeft een overzicht van recente technische inspanningen om Headless nuttiger te maken voor ontwikkelaars door Headless dichter bij de reguliere 'headful'-modus van Chrome te brengen.

Achtergrond

In 2017 introduceerde Chrome 59 de zogenaamde Headless-modus, waarmee je de browser kunt uitvoeren in een onbeheerde omgeving zonder enige zichtbare gebruikersinterface. Kortom, Chrome gebruiken zonder chroom!

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

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

Wat is er nieuw in Hoofdloos?

Voordat we ingaan op de recente Headless-verbeteringen, is het belangrijk om te begrijpen hoe de ‘oude’ Headless werkte. Het opdrachtregelfragment dat we eerder lieten zien, 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. Technisch gezien 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 .

Zoals je je misschien kunt voorstellen, bracht het implementeren en onderhouden van deze afzonderlijke Headless-browser veel technische overhead met zich mee, maar dat was niet het enige probleem. Omdat Headless een aparte implementatie was, had het zijn eigen bugs en functies die niet aanwezig waren in Headful Chrome. Dit creëerde een verwarrende situatie waarin elke geautomatiseerde browsertest in de headful-modus zou kunnen slagen, maar mislukken in de Headless-modus, of omgekeerd: een groot pijnpunt voor automatiseringsingenieurs. Het sloot ook alle geautomatiseerde tests uit die bijvoorbeeld afhankelijk waren van het installeren van een browserextensie. Hetzelfde geldt voor alle andere functionaliteit op browserniveau: tenzij Headless er een eigen, afzonderlijke implementatie van had, werd deze niet ondersteund.

In 2021 wilde het Chrome-team dit probleem oplossen en voor eens en voor altijd de Headless- en Headful-modi verenigen.

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

We zijn verheugd om aan te kondigen dat de nieuwe Headless-modus nu beschikbaar is in Chrome 112! In deze modus maakt Chrome platformvensters, maar geeft deze niet weer. Alle andere functionaliteit, bestaande en toekomstige, is zonder beperkingen beschikbaar.

Probeer de nieuwe Headless

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

chrome --headless=new

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

chrome --headless=old

Momenteel activeert het doorgeven van de opdrachtregelvlag --headless zonder een expliciete waarde nog steeds de oude Headless-modus, maar we zijn van plan deze standaard in de loop van de tijd te wijzigen in de nieuwe Headless-modus.

We zijn van plan om de oude Headless volledig uit het Chrome-binaire bestand te verwijderen en later dit jaar te stoppen met het ondersteunen van deze modus in Puppeteer. Als onderdeel van deze verwijdering zullen we de oude Headless beschikbaar maken als een afzonderlijk, zelfstandig binair bestand voor gebruikers die nog niet kunnen upgraden.

Nieuwe Headless 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();

Nieuwe Headless 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.

Headless-specifieke opdrachtregelvlaggen

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

--dump-dom

De vlag --dump-dom drukt de geserialiseerde DOM van de doelpagina af naar stdout. Hier is een voorbeeld:

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

Merk op dat dit iets anders is dan simpelweg de HTML-broncode afdrukken (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 elk <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. Het is vooral handig in combinatie met de vlag --window-size . Hier is een voorbeeld:

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. Hier is een voorbeeld:

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/

--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 maakt tijdreizen mogelijk! Nou ja, tot op zekere hoogte. Virtuele tijd 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 demopagina overwegen, die elke seconde een teller optelt, registreert en weergeeft 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 vanaf 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 erachter te komen wat er aan de hand is in geval van problemen. Gelukkig is het mogelijk om Headless Chrome te debuggen op een manier die sterk lijkt op headful Chrome. De truc is om Chrome in Headless-modus te starten 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 gewone Chrome-instantie kunnen we vervolgens Chrome DevTools foutopsporing op afstand gebruiken om verbinding te maken met het Headless-doel en het te inspecteren. Ga hiervoor naar chrome://inspect , klik op de knop Configureren… en voer het IP-adres en poortnummer van de WebSocket-URL in. In het bovenstaande voorbeeld heb ik 127.0.0.1:60926 ingevoerd. Klik op Gereed en u zou een extern doel moeten zien verschijnen met alle tabbladen en andere doelen hieronder vermeld. Klik op inspecteren en je hebt nu toegang tot Chrome DevTools die het externe Headless-doel inspecteert, 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, kunt u deze melden .