Zum Inhalt springen
Zurück zum Blog

Alternativen zu PhantomJS: Was man jetzt nutzen sollte und wie man migriert

Sorin-Gabriel MaricaZuletzt aktualisiert am 18 min read
Alternativen zu PhantomJS: Was man jetzt nutzen sollte und wie man migriert
Kurzfassung: Die beste PhantomJS-Alternative hängt davon ab, was Ihr altes Skript getan hat, denn die Entwicklung von PhantomJS wurde im März 2018 ausgesetzt. Verwenden Sie Playwright für die meisten neuen Projekte, Puppeteer für die kürzeste Node.js-Portierung, wenn Sie nur Chrome brauchen, und Selenium, wenn Ihre Tests bereits auf einem WebDriver-Grid laufen. Ist die Seite serverseitig gerendert, genügen ein HTTP-Client und ein Parser.

Die beste Alternative zu PhantomJS hängt davon ab, was Ihr altes Skript gemacht hat. Für die meisten neuen Projekte sollten Sie Playwright verwenden. Wenn Sie mit Node.js arbeiten und nur Chrome benötigen, ist Puppeteer die einfachste Lösung. Wenn Ihre Tests bereits auf einem WebDriver-Grid laufen, wechseln Sie zu Selenium mit Headless Chrome oder Firefox. Wenn die Seite serverseitig gerendert wird, benötigen Sie möglicherweise gar keinen Browser. Ein HTTP-Client und ein Parser reichen aus.

Sie benötigen einen Ersatz, da die Entwicklung von PhantomJS im März 2018 eingestellt wurde und das zugehörige GitHub-Repository nun archiviert ist. Dieser Leitfaden bestätigt die Daten, ordnet jede alte Aufgabe einem Tool zu, ordnet PhantomJS-Aufrufe Zeile für Zeile Playwright und Puppeteer zu und zeigt, wie Sie die übrig gebliebenen Pakete entfernen, die PhantomJS in Ihren Builds zurücklassen.

Das Wichtigste auf einen Blick

  • Die Entwicklung von PhantomJS wurde im März 2018 eingestellt. Die letzte Version ist 2.1.1 (Januar 2016), und das Repository wurde im Mai 2023 auf schreibgeschützt gesetzt.
  • CasperJS und Zombie.js sind ebenfalls archiviert und kommen daher als Ersatz nicht in Frage.
  • Playwright ist der am ehesten geeignete allgemeine Ersatz, und seine WebKit-Engine kommt der Darstellung von PhantomJS am nächsten.
  • Für die meisten PhantomJS-Aufrufe gibt es direkte Entsprechungen: page.open wird zu page.goto, und page.render wird zu page.screenshot oder page.pdf.
  • Wenn die Daten im ursprünglichen HTML enthalten sind, ist ein HTTP-Client schneller als jeder Browser.

Wird PhantomJS nicht mehr weiterentwickelt?

Ja. Die Entwicklung von PhantomJS wurde im März 2018 eingestellt, nachdem der leitende Betreuer 2017 zurückgetreten war. Die letzte stabile Version ist 2.1.1 vom Januar 2016, und das GitHub-Repository wurde im Mai 2023 als schreibgeschützt archiviert. Für eine bekannte Sicherheitslücke beim Lesen von Dateien, CVE-2019-17221, gibt es keine gepatchte Version.

PhantomJS war ein skriptfähiger Headless-Browser, der auf QtWebKit basierte und mit JavaScript gesteuert wurde. Ariya Hidayat veröffentlichte ihn 2011, und jahrelang war er die Standardmethode, um JavaScript-Seiten zu scrapen, Screenshots aufzunehmen, PDFs zu rendern und Frontend-Tests in der CI ohne Bildschirm auszuführen. Dann führte Chrome seinen eigenen Headless-Modus ein, und der Grund für die Pflege eines separaten WebKit-Builds schwand.

Datum

Ereignis

Quelle

Jan. 2011

Erste öffentliche Veröffentlichung

Projektgeschichte (erster Commit: Dez. 2010)

23. Januar 2016

PhantomJS 2.1 angekündigt. Das Tag 2.1.1 folgt am 24. Januar 2016 und bleibt die letzte stabile Version

Veröffentlichungen auf phantomjs.org, GitHub-Tag

April 2017

Der Betreuer Vitaly Slobodin tritt zurück, kurz nachdem „Headless Chrome“ in Chrome 59 veröffentlicht wurde

PhantomJS-Mailingliste

3. März 2018

In Issue #15344 wird angekündigt: „Archivierung des Projekts: Einstellung der Entwicklung“

GitHub-Issue

2019

CVE-2019-17221: Auslesen beliebiger Dateien über file:// URLs in page.open(), CVSS 3.1-Bewertung 7,5 (Hoch), kein Fix

NVD

30. Mai 2023

GitHub-Repository archiviert (schreibgeschützt)

GitHub-Repository-Banner

In der Praxis bedeutet „eingestellt“ vier Dinge: Es werden keine Sicherheitspatches mehr bereitgestellt, sodass die oben genannte CVE offen bleibt. Es kommen keine neuen Webplattform-Funktionen hinzu, da es sich bei der Engine um einen WebKit-Build aus dem Jahr 2016 handelt, dem jahrelange Änderungen an CSS und JavaScript fehlen. Die npm-Wrapper sind veraltet. Selenium hat die Unterstützung für PhantomJS eingestellt, sodass darauf basierende Testsuiten nicht aktualisiert werden können. Alte Binärdateien lassen sich zwar noch starten und laden einfache Seiten, werden jedoch nicht mehr gepflegt und sind für Seiten, die Sie nicht kontrollieren, unsicher.

Wird CasperJS nicht mehr weiterentwickelt?

Ja. Das GitHub-Repository von CasperJS wurde im Juni 2020 archiviert und es heißt dort, dass es nicht mehr aktiv gepflegt wird. Die letzte Version, 1.1.4-2, wurde im November 2017 veröffentlicht. CasperJS war eine Skript-Schicht, die auf PhantomJS oder SlimerJS lief, daher kann es PhantomJS nicht ersetzen. Verwenden Sie stattdessen Playwright oder Puppeteer für Ihre CasperJS-Skripte.

CasperJS-Skripte bestehen aus einer Kette von Navigationsschritten, was ihre Portierung vereinfacht. Jeder then Schritt wird zu einem „awaited“-Aufruf, und die Locators von Playwright warten selbstständig auf Elemente, sodass die meisten expliziten Wartezeiten entfallen:

CasperJS

Playwright (Node)

casper.start(url) / casper.thenOpen(url)

await page.goto(url)

casper.thenClick(sel)

await page.locator(sel).click()

casper.waitForSelector(sel, fn)

await page.locator(sel).waitFor()

casper.capture('shot.png')

await page.screenshot({ path: 'shot.png' })

Zombie.js ist ebenfalls archiviert. Die letzte Version, 6.1.4, wurde im November 2018 veröffentlicht. Es handelte sich nie um einen echten Browser: Zombie.js simulierte ein DOM innerhalb von Node.js, kann also keine Seiten rendern oder Screenshots erstellen. Für Zombie.js geschriebene Tests lassen sich am besten auf den Testrunner von Playwright portieren.

SlimerJS, das Gecko-basierte Projekt, das die API von PhantomJS nutzte, ist seit Jahren inaktiv. Keines dieser drei Tools gehört in ein neues Projekt.

Was sollte PhantomJS ersetzen?

Entscheiden Sie sich je nachdem, wofür Ihr PhantomJS-Skript verwendet wurde. Verwenden Sie Playwright für Scraping, Screenshots und browserübergreifende Tests. Verwenden Sie Puppeteer für die Chrome-Automatisierung ausschließlich unter Node und für PDFs. Verwenden Sie Selenium WebDriver, wenn Ihre Tests bereits auf einem WebDriver-Grid laufen. Befinden sich die Daten im ursprünglichen HTML-Code der Seite, verzichten Sie auf den Browser und verwenden Sie einen HTTP-Client.

Die meisten Teams haben PhantomJS für eine von wenigen Aufgaben eingesetzt. Finden Sie Ihre Aufgabe in der linken Spalte:

Was Ihr PhantomJS-Skript geleistet hat

Verwenden Sie jetzt

Warum

JavaScript-gerenderte Seiten gescrapt

Playwright oder Puppeteer

Eine aktuelle Chromium-Version, integrierte Wartefunktion und page.evaluate funktioniert genauso

Ausgelesene, serverseitig gerenderte Seiten

Ein HTTP-Client plus ein HTML-Parser

Kein Browser erforderlich, daher schneller und kostengünstiger im Betrieb

Erfasste Screenshots

Playwright oder Puppeteer page.screenshot()

Screenshots von ganzen Seiten und einzelnen Elementen sind integriert

Generierte PDFs

Puppeteer page.pdf() oder Playwright page.pdf() (nur Chromium)

„Print-to-PDF“ ersetzt page.render('file.pdf')

Ausführung von Unit-Tests in Karma

Kurzfristig: Karma-Chrome-Headless-Launcher, langfristig: ein moderner Test-Runner

Karma selbst ist veraltet

Selenium-Tests wurden über GhostDriver ausgeführt

Selenium mit Headless-Chrome oder Firefox

Selenium 4 hat die Unterstützung für PhantomJS eingestellt

Benötigte speziell WebKit-Rendering

Playwright WebKit

Die Engine, die dem QtWebKit von PhantomJS am nächsten kommt

Führte Java-Tests ohne echten Browser aus

HtmlUnit

Ein gepflegter, GUI-loser Browser für Java

Kein einzelnes Tool hat PhantomJS ersetzt. Moderne Browser verfügen mittlerweile über einen echten Headless-Modus und werden durch eine Reihe von Bibliotheken gesteuert. Deshalb ist eine Entscheidung auf Skript-Basis besser als eine teamweite Auswahl.

Welche PhantomJS-Alternativen werden noch gepflegt?

Playwright, Puppeteer und Selenium werden aktiv weiterentwickelt und decken nahezu jeden Anwendungsfall von PhantomJS ab. Headless Chrome lässt sich zudem eigenständig über die Befehlszeile ausführen. HtmlUnit wird für Java-Tests ohne echten Browser weiterentwickelt. Splash gibt es noch für Scrapy-Nutzer, wird aber nur selten ausgeliefert. CasperJS, Zombie.js und PhantomJS selbst sind archiviert.

Tool

Status

Protokoll

Sprachen

Engines

Am besten geeignet für

Playwright

Aktiv

Chrome DevTools-Protokoll für Chromium; Playwrights eigene Protokolle für Firefox und WebKit

JavaScript/TypeScript, Python, Java, .NET

Chromium, Firefox, WebKit

Die meisten neuen Arbeiten, browserübergreifende Tests, WebKit-Parität

Puppeteer

Aktiv

Chrome DevTools-Protokoll; WebDriver BiDi für Firefox

JavaScript/TypeScript

Chrome, Firefox

Node.js Chrome-Automatisierung, PDFs

Selenium WebDriver

Aktiv

W3C WebDriver, WebDriver BiDi

Java, Python, C#, Ruby, JavaScript

Alle gängigen Browser

Bestehende Testsuiten, Test-Grids, viele Sprachen

Headless Chrome (CLI)

Aktiv

Befehlszeilenoptionen; Chrome DevTools-Protokoll

Beliebig (Shell)

Chrome

Einmalige Screenshots, PDFs, DOM-Dumps

HtmlUnit

Aktiv (5.6.0, Oktober 2026)

In-Process

Java

Eigene Engine, kein Rendering

Java-Tests ohne Browser

Splash

Geringe Aktivität (letzter Code-Push im August 2024)

HTTP-API plus Lua-Skripte

Beliebig (über HTTP)

WebKit-basiert

Bestehende Scrapy-Konfigurationen

CasperJS, Zombie.js, PhantomJS

Archiviert

k. A.

k. A.

k. A.

Migration

Playwright

Playwright wird von Microsoft gepflegt und steuert Chromium, Firefox und WebKit über eine einzige API an. Seine Locators warten darauf, dass Elemente angehängt, sichtbar und stabil sind, bevor sie aktiv werden, wodurch der Großteil des Timing-Codes, den PhantomJS-Skripte enthielten, entfällt. Jeder Browserkontext ist isoliert und verfügt über eigene Cookies und Speicher, sodass Sie viele Sitzungen in einem einzigen Browserprozess ausführen können. Außerdem enthält es einen Testrunner mit Tracing, Screenshots bei Fehlern und parallelen Workern.

Für PhantomJS-Nutzer ist die WebKit-Engine das entscheidende Detail. Wenn Sie alte PhantomJS-Screenshots reproduzieren oder überprüfen möchten, wie eine Seite in einer Safari-ähnlichen Engine gerendert wird, starten Sie webkit anstelle von chromium und lassen Sie den Rest des Skripts unverändert.

Python-Teams erhalten dieselbe API über pip install playwright gefolgt von playwright install, und Java-Teams können das com.microsoft.playwright Maven-Paket hinzufügen. Unser Playwright-Leitfaden zum Web-Scraping behandelt Selektoren, Paginierung und Datenexport, und die Playwright-Dokumentation listet alle unten verwendeten APIs auf.

Puppeteer

Puppeteer wird vom Chrome-Team gepflegt und ist in erster Linie für Node.js konzipiert. Es ist die einfachste Portierung von PhantomJS-JavaScript, da das asynchrone Seitenobjekt und page.evaluate vertraut an, und ein typisches Skript behält seine Struktur bei. Es bewältigt Screenshots und die PDF-Erstellung gut und steuert nun neben Chrome auch Firefox über WebDriver BiDi an.

Der wesentliche Unterschied zwischen PhantomJS und Puppeteer liegt in der Engine. Puppeteer steuert eine aktuelle Chrome-Version an, während PhantomJS einen WebKit-Build aus dem Jahr 2016 verwendet. Seiten, die in PhantomJS aufgrund von modernem JavaScript oder CSS nicht richtig funktionieren, werden in Puppeteer in der Regel ohne besondere Maßnahmen korrekt gerendert.

Eine vollständige Anleitung zu Selektoren, Navigation und Datenextraktion finden Sie in unserem Leitfaden zum Scraping mit Puppeteer und Node.js. Die Puppeteer-Dokumentation behandelt Startoptionen, einschließlich des headless: 'shell' unten beschriebenen Modus.

Selenium WebDriver

Selenium implementiert den W3C-WebDriver-Standard mit offiziellen Bindings für Java, Python, C#, Ruby und JavaScript. Es steuert alle gängigen Browser an, lässt sich über Selenium Grid skalieren und wird um WebDriver BiDi für bidirektionale Ereignisse wie Konsolenprotokolle und Netzwerkaktivität erweitert. Im Gegensatz zu Puppeteer ist es für seine Kernbefehle nicht auf das Chrome DevTools-Protokoll angewiesen. Es ist die naheliegende Lösung für Java- und Ruby-Teams, die zuvor PhantomJS verwendet haben, sowie für Testsuiten, die PhantomJS über GhostDriver ausgeführt haben.

Die Python-Bindungen haben PhantomJS in Version 3.8.1 als veraltet markiert und in 4.0 Alpha 6 entfernt, sodass webdriver.PhantomJS() es existiert nicht mehr. Wechseln Sie zu Chrome oder Firefox mit der „headless“-Option, und Ihre Locators und Assertions funktionieren weiterhin. In Java bedeutet das new ChromeOptions().addArguments("--headless=new").

Wenn Sie in Python ganz von vorne anfangen, lesen Sie unseren Leitfaden zum Erstellen eines Selenium-Scrapers in Python. Die Selenium-Dokumentation behandelt Treiber, Wartezeiten und die Grid-Einrichtung.

Headless Chrome als eigenständiges Programm

Chrome läuft seit Chrome 59 im Jahr 2017 im Headless-Modus. Seit Chrome 112 entspricht der Headless-Modus dem regulären Chrome-Browser, nur ohne sichtbare Fenster. Die ältere, separate Implementierung besteht als eigenständige Binärdatei namens chrome-headless-shell (seit Chrome 132), die Puppeteer als headless: 'shell'.

Einmalige Aufgaben benötigen keine Bibliothek. Ein einziger Befehl ersetzt ein kurzes PhantomJS-Skript:

google-chrome --headless --screenshot=shot.png --window-size=1280,800 https://books.toscrape.com/
google-chrome --headless --print-to-pdf=page.pdf https://books.toscrape.com/
google-chrome --headless --dump-dom https://books.toscrape.com/ > page.html

Die Flags sind in der Dokumentation zum Headless-Modus von Chrome beschrieben. Python-Leser können die Optionen in unserer Übersicht über Headless-Browser in Python vergleichen.

HtmlUnit und Splash

HtmlUnit ist ein Browser ohne grafische Benutzeroberfläche für Java-Programme. Er führt JavaScript aus, rendert jedoch keine Pixel, sodass er sich für Java-Tests eignet, die die Seitenlogik und Formulare überprüfen, nicht jedoch für Screenshots. Er wird aktiv weiterentwickelt, zuletzt erschien im Oktober 2026 die Version 5.6.0.

Splash ist ein skriptfähiger Rendering-Dienst mit einer HTTP-API und Lua-Skripten, der meist über Scrapy-Splash genutzt wird. Für Teams, die ihn bereits einsetzen, funktioniert er weiterhin, doch die Code-Aktivität ist seit 2024 gering. Für neue Scraping-Projekte ist Playwright die sicherere Wahl.

Wenn Sie Puppeteer eher mit seinen eigenen Konkurrenten vergleichen möchten, anstatt PhantomJS zu ersetzen, sehen Sie sich unseren Vergleich der Puppeteer-Alternativen an.

Wie lassen sich PhantomJS-Befehle auf Playwright und Puppeteer abbilden?

Die meisten PhantomJS-Aufrufe haben sowohl in Playwright als auch in Puppeteer eine Eins-zu-Eins-Entsprechung, sodass eine Portierung größtenteils nur aus einer Umbenennung besteht. page.open wird zu page.goto, page.render wird zu page.screenshot oder page.pdf, page.evaluate behält seinen Namen, und Callbacks werden zu async/await. Die eigentliche Änderung betrifft das Warten. Ersetzen Sie feste Timeouts durch Wartezeiten basierend auf Selektoren oder dem Ladestatus.

PhantomJS

Playwright (Node.js)

Puppeteer

require('webpage').create()

const page = await browser.newPage()

const page = await browser.newPage()

page.open(url, callback)

await page.goto(url)

await page.goto(url)

page.evaluate(fn)

await page.evaluate(fn, arg)

await page.evaluate(fn, ...args)

page.render('shot.png')

await page.screenshot({ path: 'shot.png', fullPage: true })

await page.screenshot({ path: 'shot.png', fullPage: true })

page.render('doc.pdf') mit page.paperSize

await page.pdf({ path: 'doc.pdf', format: 'A4' }) (nur Chromium)

await page.pdf({ path: 'doc.pdf', format: 'A4' })

page.viewportSize = { width, height }

await page.setViewportSize({ width, height })

await page.setViewport({ width, height })

page.settings.userAgent = ua

await browser.newContext({ userAgent: ua })

await page.setUserAgent({ userAgent: ua })

phantom.addCookie(cookie)

await context.addCookies([cookie])

await browser.setCookie(cookie)

page.onConsoleMessage = fn

page.on('console', (msg) => …)

page.on('console', (msg) => …)

page.onResourceRequested = fn

await page.route('**/*', (route) => …)

await page.setRequestInterception(true) sowie page.on('request', …)

page.injectJs(file) / page.includeJs(url)

await page.addScriptTag({ path }) oder ({ url })

await page.addScriptTag({ path }) oder ({ url })

page.sendEvent('click', x, y)

await page.locator(sel).click()

await page.click(sel)

setTimeout wartet / page.onLoadFinished

await page.locator(sel).waitFor() oder await page.waitForLoadState()

await page.waitForSelector(sel)

--proxy=host:port Befehlszeilenoption

chromium.launch({ proxy: { server: 'http://host:port' } })

puppeteer.launch({ args: ['--proxy-server=host:port'] })

system.args

process.argv

process.argv

phantom.exit()

await browser.close()

await browser.close()

In den jüngsten Puppeteer-Versionen wurden zwei Zeilen geändert. Cookies werden nun im Browser oder im Browserkontext gespeichert (browser.setCookie), da die Cookie-Methoden auf Seitenebene veraltet sind. Außerdem setUserAgent erfordert ein Options-Objekt. Ältere Tutorials, die page.setCookie , laufen zwar weiterhin, geben jedoch Veraltungswarnungen aus.

Vorher: ein PhantomJS-Skript

Dieses Skript öffnet den Übungsshop „Books to Scrape“, liest den Seitentitel und die ersten fünf Buchlinks aus, speichert einen Screenshot und beendet das Skript:

// legacy.js (PhantomJS 2.1.1): run with `phantomjs legacy.js`
var page = require('webpage').create();
var url = 'https://books.toscrape.com/';

page.viewportSize = { width: 1280, height: 800 };

page.open(url, function (status) {
  if (status !== 'success') {
    console.log('Failed to load ' + url);
    phantom.exit(1);
  }
  var data = page.evaluate(function () {
    var links = document.querySelectorAll('article.product_pod h3 a');
    return {
      title: document.title.trim(),
      books: Array.prototype.slice.call(links, 0, 5).map(function (a) {
        return { title: a.getAttribute('title'), href: a.href };
      })
    };
  });
  console.log(JSON.stringify(data, null, 2));
  page.render('books.png');
  phantom.exit();
});

Danach: dasselbe Skript in Playwright

Installieren Sie Playwright mit npm install playwright und npx playwright install chromium, dann führen Sie den Port als ES-Modul aus:

// modern.mjs (Playwright for Node.js): run with `node modern.mjs`
import { chromium } from 'playwright';

const url = 'https://books.toscrape.com/';
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1280, height: 800 } });

try {
  await page.goto(url);
  await page.locator('article.product_pod').first().waitFor();

  const data = await page.evaluate(() => ({
    title: document.title.trim(),
    books: [...document.querySelectorAll('article.product_pod h3 a')]
      .slice(0, 5)
      .map((a) => ({ title: a.getAttribute('title'), href: a.href })),
  }));

  console.log(JSON.stringify(data, null, 2));
  await page.screenshot({ path: 'books.png', fullPage: true });
} finally {
  await browser.close();
}

Beide Skripte geben dieselben Daten aus:

{
  "title": "All products | Books to Scrape - Sandbox",
  "books": [
    {
      "title": "A Light in the Attic",
      "href": "https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html"
    },
    {
      "title": "Tipping the Velvet",
      "href": "https://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html"
    },
    {
      "title": "Soumission",
      "href": "https://books.toscrape.com/catalogue/soumission_998/index.html"
    },
    {
      "title": "Sharp Objects",
      "href": "https://books.toscrape.com/catalogue/sharp-objects_997/index.html"
    },
    {
      "title": "Sapiens: A Brief History of Humankind",
      "href": "https://books.toscrape.com/catalogue/sapiens-a-brief-history-of-humankind_996/index.html"
    }
  ]
}

Die Struktur ändert sich kaum. Der Callback wird zu einem Top-Level-Element await, try/finally ersetzt die verstreuten phantom.exit() Aufrufe, sodass der Browser immer geschlossen wird, und eine explizite Wartezeit bei den Produktkarten ersetzt die Hoffnung, dass page.open spät genug ausgelöst wird. Die Funktion, die Sie an page.evaluate , wird weiterhin innerhalb der Seite ausgeführt, sodass Ihr DOM-Code unverändert übernommen wird und Sie die ES5-Workarounds wie Array.prototype.slice.call.

Um stattdessen Puppeteer zu verwenden, importieren Sie puppeteer, rufen Sie puppeteer.launch(), legen Sie den Viewport mit page.setViewport()und ersetze die Locator-Wartezeit durch page.waitForSelector('article.product_pod'). Alles andere bleibt unverändert.

Wie migriert man ein PhantomJS-Skript Schritt für Schritt?

Erstellen Sie eine Bestandsaufnahme der Funktionen der einzelnen Skripte und wählen Sie dann für jeden Job den passenden Ersatz aus. Installieren Sie Playwright oder Puppeteer und portieren Sie die Aufrufe mithilfe der Zuordnungstabelle. Ersetzen Sie feste Wartezeiten durch Selektor-Wartezeiten und vergleichen Sie die Ausgaben mit alten Screenshots oder Daten. Entfernen Sie schließlich die PhantomJS-Binärdateien und Wrapper-Pakete aus Ihren Abhängigkeiten, CI-Images und Dockerfiles.

  1. Bestandsaufnahme. Durchsuchen Sie den Quellcode nach phantomjs, require('webpage'), casper, GhostDriverund karma-phantomjs-launcher. Überprüfen Sie auch die CI-Konfigurationen und Dockerfiles, da sich PhantomJS oft in einem Build-Schritt und nicht im Anwendungscode versteckt.
  2. Ordnen Sie jedes Skript nach Job ein. Verwenden Sie dazu die obige Schnellauswahltabelle. Ein Screenshot-Job und eine Selenium-Suite benötigen unterschiedliche Ersatzlösungen, selbst innerhalb desselben Repositorys.
  3. Installieren Sie den Ersatz. Playwright lädt seine eigenen Browser-Builds mit npx playwright install, daher benötigt CI diesen Schritt oder das offizielle Docker-Image. Python-Teams verwenden pip install playwright und playwright install stattdessen.
  4. Portieren Sie die Aufrufe. Arbeiten Sie die Zuordnungstabelle durch. Callbacks werden zu async/await, und Eigenschaften von Ereignisbehandlungsroutinen wie page.onConsoleMessage zu page.on(...) zu „Listenern“.
  5. Beheben Sie die Wartezeiten. Dies ist die häufigste Ursache für Abweichungen nach einer Migration. Ersetzen Sie jedes setTimeout und onLoadFinished Trick durch eine Wartezeit auf das Element oder den Ladezustand, den Sie tatsächlich benötigen.
  6. Vergleichen Sie die Ausgabe. Vergleichen Sie den HTML-Code, die extrahierten Daten oder Screenshots mit einem PhantomJS-Lauf. Rechnen Sie mit einigen Darstellungsunterschieden, da die neue Engine Schriftarten, Layout und CSS unterstützt, die WebKit aus dem Jahr 2016 nicht unterstützte.
  7. Aktualisieren Sie CI und Container. Installieren Sie die Systembibliotheken, die der neue Browser benötigt, und entfernen Sie die PhantomJS-Binärdatei sowie alle OPENSSL_CONF Fontconfig-Workarounds, die Sie dafür hinzugefügt haben.
  8. Löschen Sie die Überbleibsel. Entfernen Sie die alten Pakete und Launcher, wie im Folgenden beschrieben.

Was ersetzt „karma-phantomjs-launcher“, „phantomjs-prebuilt“ und „GhostDriver“?

Ersetzen Sie „karma-phantomjs-launcher“ durch den Chrome-Headless-Launcher von Karma und planen Sie anschließend eine Abkehr von Karma, das selbst veraltet ist. Entfernen Sie „phantomjs-prebuilt“, das von npm als veraltet markiert wird, und portieren Sie dessen Skripte auf Playwright oder Puppeteer. Ersetzen Sie GhostDriver-Sitzungen durch die Chrome- oder Firefox-Treiber von Selenium im Headless-Modus, da PhantomJS in Selenium 4 entfernt wurde.

In diesen Überresten hält sich PhantomJS in der Regel am längsten, da sie in Test- und Browser-Automatisierungstools verbleiben, die niemand anfasst, bis ein Build fehlschlägt.

Karma. Das Repository „karma-phantomjs-launcher“ wurde nach seiner letzten Aktivität im Jahr 2017 archiviert. Die schnelle Lösung besteht darin, karma-chrome-launcher und browsers: ['ChromeHeadless'] in karma.conf.js. Dadurch bleibt die Testsuite erfolgreich, aber Karma ist das größere Problem. Der Veraltungshinweis von Karma besagt, dass es keine neuen Funktionen oder allgemeinen Fehlerbehebungen mehr akzeptiert. Angular hat Jest und Web Test Runner als Migrationspfade hinzugefügt, und beide eignen sich für Unit-Tests, die früher in PhantomJS liefen.

npm-Pakete. phantomjs-prebuilt (letzte Version 2.1.16) ist auf npm mit „Dieses Paket ist nun veraltet“ gekennzeichnet, und das ältere phantomjs Paket verweist darauf. Beide laden die nicht mehr gepflegte Binärdatei 2.1.1 herunter. Entfernen Sie diese mit npm uninstall phantomjs-prebuilt phantomjsund überprüfen Sie anschließend Ihre Lockfile, da andere Entwicklungsabhängigkeiten diese manchmal mit einbinden.

Selenium und GhostDriver. DesiredCapabilities.PHANTOMJS und webdriver.PhantomJS() sind in Selenium 4 nicht mehr enthalten. In Python erfordert der Austausch drei Zeilen:

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)

Der Selenium Manager findet oder lädt einen passenden Treiber herunter, sodass Sie keine separate GhostDriver-Binärdatei mehr bereitstellen müssen. Bei Firefox funktioniert es genauso mit FirefoxOptions und dem -headless Argument.

Docker-Images. Entfernen Sie alle apt-get install phantomjs oder globale „npm install“-Installationen von PhantomJS. Verwenden Sie das offizielle Playwright-Image oder befolgen Sie die Anleitung von Puppeteer für die Systembibliotheken, die Chrome in einem Container benötigt.

Brauchen Sie überhaupt einen headless Browser?

Oftmals nicht. Viele PhantomJS-Scraper wurden geschrieben, als das Rendern noch sicherer erschien, aber wenn die Daten bereits im ursprünglichen HTML der Seite oder in einem JSON-Endpunkt enthalten sind, ist ein HTTP-Client in Kombination mit einem Parser schneller und einfacher. Überprüfen Sie zunächst den Quellcode der Seite und verwenden Sie einen Browser nur dann, wenn Inhalte erst nach der Ausführung von JavaScript angezeigt werden.

Eine kurze Überprüfung dauert nur eine Minute:

  1. Öffnen Sie die Seite und zeigen Sie deren Quelltext an, nicht das inspizierte DOM.
  2. Suchen Sie im Quellcode nach einem Wert, den Sie extrahieren möchten, beispielsweise einem Preis oder einem Produktnamen.
  3. Ist er nicht vorhanden, öffne den Reiter „Netzwerk“ in den Entwicklertools deines Browsers und suche nach XHR- oder Fetch-Anfragen, die JSON zurückgeben.

Wenn der Wert in Schritt 2 gefunden wird, können eine einfache HTTP-Anfrage und ein Parser ihn mit einem Bruchteil der Zeit und des Speichers abrufen, die ein Browser benötigt. Wenn in Schritt 3 ein JSON-Endpunkt gefunden wird, rufen Sie ihn direkt auf und überspringen Sie auch das HTML-Parsing. Unser Vergleich zwischen Cheerio und Puppeteer zeigt beide Ansätze nebeneinander in Node.js.

Behalte einen Browser für die Aufgaben, die einen erfordern: Klicken durch Abläufe, Anmelden, unendliches Scrollen, Screenshots, PDFs und visuelle Tests.

Wann sollten Sie aufhören, Browser selbst auszuführen?

Hören Sie mit dem Selbsthosting auf, wenn die Kosten für die Browserwartung den Nutzen der Skripte übersteigen. Häufige Anzeichen sind Abstürze und Speicherlecks bei großem Umfang, Abweichungen bei den Browserversionen in der CI, blockierte Anfragen sowie die Notwendigkeit, Seiten aus verschiedenen Ländern und auf unterschiedlichen Geräten zu überprüfen. Eine verwaltete API führt den Browser aus und gibt HTML, Daten oder Screenshots über einfache HTTP-Anfragen zurück.

Einen Headless-Browser zu betreiben ist einfach. Hunderte zu betreiben ist eine ganz andere Aufgabe. Sie müssen Parallelitätsgrenzen verwalten, Chrome-Prozesse bereinigen, die nie beendet werden, Browser-Builds auf den Laptops der Entwickler und in der CI synchron halten sowie mit Websites umgehen, die den Datenverkehr aus Rechenzentren blockieren. Wenn Sie eine Seite so sehen müssen, wie sie Besucher in einem anderen Land sehen, benötigen Sie zudem Infrastruktur in diesem Land.

Die Browser-API von WebScrapingAPI entlastet Ihre Server von dieser Arbeit. Sie senden eine URL mit Wartezeiten, wie zum Beispiel wait_until oder wait_for_css, sowie Seitenaktionen wie Klicken, Scrollen, Eingeben, Auswählen und Absenden. Sie gibt gerendertes HTML, ein JSON-DOM, extrahierte Felder oder einen Base64-Screenshot zurück. Es handelt sich um eine REST-Schnittstelle im Request-Response-Modus ohne aktive Browsersitzung, sodass Sie weder Puppeteer noch Playwright daran anbinden müssen. Sie beschreiben die Schritte in der Anfrage und erhalten das Ergebnis.

Für die Screenshot- und QA-Aufgaben, die bisher oft von PhantomJS übernommen wurden, überprüft unsere Lösung für Website-Tests über verschiedene Märkte und Geräte hinweg öffentliche Seiten nach Land, Gerät und Viewport und speichert Screenshots als Nachweis.

Wenn Sie lediglich gerendertes HTML benötigen, vergleichen Sie die Webzugriffs-APIs, um die für Sie am besten geeignete Lösung zu finden.

FAQ

Ist die Nutzung von PhantomJS noch sicher?

Nicht für nicht vertrauenswürdige Seiten. PhantomJS hat seit der Einstellung der Entwicklung im Jahr 2018 keine Sicherheitspatches mehr erhalten, und die Sicherheitslücke CVE-2019-17221 ermöglicht es einer Seite, lokale Dateien zu lesen, page.open() , solange keine gepatchte Version vorliegt. Falls Sie es vorübergehend behalten müssen, führen Sie es während der Migration ausschließlich auf Seiten aus, die Sie kontrollieren, und zwar in einem isolierten Container.

Kann ich PhantomJS noch über npm installieren?

Das geht zwar, sollte aber vermieden werden. Das phantomjs-prebuilt Paket ist auf npm als veraltet gekennzeichnet, und die Binärdateien stammen aus der nicht mehr gepflegten Version 2.1.1. Bei neuen Projekten sollten stattdessen Playwright oder Puppeteer installiert werden. Beide laden einen aktuellen Browser-Build herunter und verfügen über aktive Betreuer sowie eine Dokumentation.

Ist Playwright oder Puppeteer besser geeignet, um PhantomJS zu ersetzen?

Playwright eignet sich für die meisten Teams. Es unterstützt Chromium, Firefox und WebKit, verfügt über Python-, Java- und .NET-Bindungen und wartet automatisch auf Elemente. Puppeteer eignet sich gut für Node-Projekte, die nur Chrome benötigen, oder für die PDF-Erstellung. Beide portieren PhantomJS-Skripte mit ähnlichem Aufwand, da page.evaluate beide auf die gleiche Weise funktionieren.

Unterstützt Selenium PhantomJS noch?

Nein. Selenium hat PhantomJS in Version 3.8.1 als veraltet markiert und in Selenium 4 entfernt, sodass webdriver.PhantomJS() und GhostDriver-Sitzungen funktionieren nicht mehr. Stellen Sie diese Tests auf Chrome oder Firefox mit der „headless“-Option um. Ihre WebDriver-Locators und -Assertions bleiben größtenteils unverändert, sodass der Portierungsaufwand in der Regel gering ist.

Was hat PhantomJS in Karma ersetzt?

Der Chrome-Headless-Launcher von Karma ist der übliche Ersatz für den „karma-phantomjs-launcher“. Karma selbst ist mittlerweile jedoch veraltet. Für eine längerfristige Lösung sollten Sie die Unit-Tests auf einen gepflegten Runner wie Jest oder Web Test Runner verlagern, die Angular als Migrationspfade hinzugefügt hat.

Welche PhantomJS-Alternative nutzt WebKit?

Playwright. Es enthält neben Chromium und Firefox auch einen WebKit-Build, wodurch es in der Darstellung der QtWebKit-Engine von PhantomJS am nächsten kommt. Verwenden Sie es, wenn Sie alte PhantomJS-Screenshots reproduzieren oder eine Safari-ähnliche Darstellung testen müssen. Für alle anderen Fälle ist Chromium der übliche Standard.

Welche PhantomJS-Alternative solltest du wählen?

Wählen Sie je nach Aufgabe. Verwenden Sie Playwright für die meisten Scraping-Aufgaben, Screenshots und browserübergreifende Tests, Puppeteer für die Chrome-Automatisierung mit Node.js und PDFs sowie Selenium für bestehende WebDriver-Suiten in beliebigen Sprachen. Bevor du einen Scraper portierst, prüfe, ob die Daten bereits im HTML enthalten sind, denn der schnellste Browser ist der, den du nicht ausführst. Lösche anschließend die PhantomJS-Binärdateien, Wrapper und Launcher, damit nichts die alte Engine wieder in deine Builds zieht.

Verzichte auf die Browser-Wartung

Rendern Sie JavaScript-Seiten, ohne einen Browser zu starten. Senden Sie eine URL an die Scraper-API und erhalten Sie das gerenderte HTML zurück. Beginnen Sie mit 5.000 kostenlosen Anfragen. JavaScript-Rendering und Geotargeting kosten keine zusätzlichen Credits, und fehlgeschlagene Anfragen werden nicht in Rechnung gestellt.

Entdecke die Scraper-API

Über den Autor

Sorin-Gabriel Marica, Full-Stack-Entwickler @ WebScrapingAPI

Sorin-Gabriel Marica

Full-Stack-Entwickler

Sorin Marica ist Full-Stack- und DevOps-Entwickler bei WebScrapingAPI, wo er Produktfunktionen entwickelt und die Infrastruktur wartet, die für einen reibungslosen Betrieb der Plattform sorgt.

Web-Scraping mit AWS Lambda: Leitfaden für Python und Java 2026
Anleitungen

Web-Scraping mit AWS Lambda: Leitfaden für Python und Java 2026

TL;DR: Kurz gesagt: Web-Scraping mit AWS Lambda funktioniert am besten, wenn jeder Aufruf kurz, begrenzt und unabhängig wiederholbar ist. Beginnen Sie mit direktem HTTP, AWS SAM und S3 und fügen Sie erst dann SQS, Container, Browser-Rendering, Proxys oder eine verwaltete Abrufebene hinzu, wenn sich im Rahmen der Arbeitslast herausstellt, dass diese erforderlich sind.

Suciu Dan26 min read
Artikel lesen
So verwenden Sie GoSpider: Crawlen, URLs bereinigen und Daten extrahieren
Anleitungen

So verwenden Sie GoSpider: Crawlen, URLs bereinigen und Daten extrahieren

TL;DR: GoSpider ist ein Befehlszeilen-Crawler zum Auffinden von URLs, kein vollständiger Scraper für strukturierte Daten. Diese Anleitung zur Verwendung von GoSpider zeigt einen begrenzten Crawl, die saubere Verarbeitung der Ausgabe, die Übergabe von Colly an CSV sowie einen Diagnosepfad für 403-Antworten oder Seiten, die eine JavaScript-Darstellung erfordern.

Suciu Dan20 min read
Artikel lesen
Wie man Redfin scrappt: Python-Leitfaden für Immobiliendaten
Anleitungen

Wie man Redfin scrappt: Python-Leitfaden für Immobiliendaten

TL;DR: Redfin stellt versteckte API-Endpunkte zur Verfügung, die strukturiertes JSON für Immobilienangebote zurückgeben, wodurch das fragile HTML-Parsing vollständig übersprungen werden kann. Diese Anleitung führt Sie durch den Aufbau eines Python-Scrapers, der Miet- und Verkaufsdaten extrahiert, nach Standort sucht, neue Angebote über XML-Sitemaps überwacht und saubere Ergebnisse in CSV oder JSON exportiert.

Suciu Dan11 min read
Artikel lesen

Los geht’s

Sind Sie bereit, Ihre Datenerfassung zu erweitern?

Schließen Sie sich den über 2.000 Unternehmen an, die WebScrapingAPI nutzen, um Webdaten im Unternehmensmaßstab ohne zusätzlichen Infrastrukturaufwand zu extrahieren.