Aller au contenu
Retour au blog

Alternatives à PhantomJS : quelles solutions utiliser aujourd'hui et comment effectuer la migration ?

Sorin-Gabriel MaricaDernière mise à jour le 21 min read
Alternatives à PhantomJS : quelles solutions utiliser aujourd'hui et comment effectuer la migration ?
En bref : La meilleure alternative à PhantomJS dépend de ce que faisait votre ancien script, car le développement de PhantomJS a été suspendu en mars 2018. Utilisez Playwright pour la plupart des nouveaux projets, Puppeteer pour le portage Node.js le plus court si vous n'avez besoin que de Chrome, et Selenium si vos tests tournent déjà sur une grille WebDriver. Si la page est rendue côté serveur, un client HTTP et un analyseur suffisent.

Le choix de la meilleure alternative à PhantomJS dépend de ce que faisait votre ancien script. Pour la plupart des nouveaux projets, utilisez Playwright. Si vous utilisez Node.js et que vous n'avez besoin que de Chrome, Puppeteer est la solution la plus simple. Si vos tests s'exécutent déjà sur une grille WebDriver, passez à Selenium avec Chrome ou Firefox en mode headless. Si la page est rendue côté serveur, vous n'aurez peut-être pas besoin de navigateur du tout. Un client HTTP et un analyseur suffiront.

Vous avez besoin d’une solution de remplacement car le développement de PhantomJS a été suspendu en mars 2018 et son dépôt GitHub est désormais archivé. Ce guide confirme ces dates, associe chaque ancienne tâche à un outil, mappe ligne par ligne les appels PhantomJS vers Playwright et Puppeteer, et explique comment supprimer les paquets résiduels qui maintiennent PhantomJS dans vos builds.

Points clés

  • Le développement de PhantomJS a été suspendu en mars 2018. La dernière version est la 2.1.1 (janvier 2016), et le dépôt est devenu en lecture seule en mai 2023.
  • CasperJS et Zombie.js sont également archivés ; ils ne constituent donc pas des alternatives valables.
  • Playwright est le substitut général le plus proche, et son moteur WebKit est celui qui se rapproche le plus du rendu de PhantomJS.
  • La plupart des appels PhantomJS ont des équivalents directs : page.open devient page.goto, et page.render devient page.screenshot ou page.pdf.
  • Si les données se trouvent dans le code HTML initial, un client HTTP est plus rapide que n'importe quel navigateur.

PhantomJS a-t-il été abandonné ?

Oui. Le développement de PhantomJS a été suspendu en mars 2018, après le départ de son responsable principal en 2017. La dernière version stable est la 2.1.1, datant de janvier 2016, et le dépôt GitHub a été archivé en lecture seule en mai 2023. Une vulnérabilité connue liée à la lecture de fichiers, CVE-2019-17221, n'a pas fait l'objet d'un correctif.

PhantomJS était un navigateur sans interface graphique scriptable, basé sur QtWebKit et contrôlé via JavaScript. Ariya Hidayat l’a lancé en 2011, et pendant des années, il a constitué la solution par défaut pour extraire des données de pages JavaScript, réaliser des captures d’écran, générer des PDF et exécuter des tests front-end en intégration continue (CI) sans écran. Puis Chrome a intégré son propre mode sans interface graphique, et la raison de maintenir une version distincte de WebKit s’est estompée.

Date

Événement

Source

Janvier 2011

Première version publique

Historique du projet (premier commit en décembre 2010)

23 janvier 2016

Annonce de PhantomJS 2.1. La version 2.1.1 suit le 24 janvier 2016 et reste la dernière version stable

Versions sur phantomjs.org, balise GitHub

Avril 2017

Le responsable du projet, Vitaly Slobodin, quitte ses fonctions, peu après l'intégration de Chrome « headless » dans la version 59 de Chrome

Liste de diffusion PhantomJS

3 mars 2018

Le ticket n° 15344 annonce « Archivage du projet : suspension du développement »

Tique GitHub

2019

CVE-2019-17221 : lecture arbitraire de fichiers via des file:// URL dans page.open(), score CVSS 3.1 : 7,5 (Élevé), aucun correctif

NVD

30 mai 2023

Dépôt GitHub archivé (en lecture seule)

Bannière du dépôt GitHub

Concrètement, « abandonné » signifie quatre choses. Aucun correctif de sécurité n’est publié, donc le CVE ci-dessus reste ouvert. Aucune nouvelle fonctionnalité de la plateforme web n’est ajoutée, car le moteur est une version de WebKit datant de 2016 qui ne prend pas en charge les évolutions de CSS et de JavaScript intervenues depuis plusieurs années. Les wrappers npm sont obsolètes. Selenium a supprimé la prise en charge de PhantomJS ; les suites de tests qui s'appuient sur ce dernier ne peuvent donc plus être mises à jour. Les anciens binaires démarrent toujours et chargent des pages simples, mais ils ne sont plus maintenus et présentent un risque de sécurité pour les pages que vous ne contrôlez pas.

CasperJS est-il abandonné ?

Oui. Le dépôt GitHub de CasperJS a été archivé en juin 2020 et indique que le projet n’est plus activement maintenu. Sa dernière version, la 1.1.4-2, a été publiée en novembre 2017. CasperJS était une couche de script fonctionnant sur PhantomJS ou SlimerJS ; il ne peut donc pas remplacer PhantomJS. Transférez plutôt vos scripts CasperJS vers Playwright ou Puppeteer.

Les scripts CasperJS sont une chaîne d’étapes de navigation, ce qui facilite leur portage. Chaque then étape devient un appel « awaited », et les localisateurs de Playwright attendent les éléments de manière autonome, ce qui fait disparaître la plupart des attentes explicites :

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 est également archivé. Sa dernière version, la 6.1.4, a été publiée en novembre 2018. Il ne s’agissait pas d’un véritable navigateur : il simulait un DOM au sein de Node.js, il ne peut donc ni afficher de pages ni capturer de captures d’écran. Les tests écrits pour cet outil se portent mieux vers l’exécuteur de tests de Playwright.

SlimerJS, le projet basé sur Gecko qui partageait l’API de PhantomJS, est inactif depuis des années. Aucun de ces trois outils n’a sa place dans un nouveau projet.

Que devrait-on utiliser à la place de PhantomJS ?

Faites votre choix en fonction de ce que faisait votre script PhantomJS. Utilisez Playwright pour le scraping, les captures d’écran et les tests multi-navigateurs. Utilisez Puppeteer pour l’automatisation de Chrome sous Node.js uniquement et pour les PDF. Utilisez Selenium WebDriver si vos tests s’exécutent déjà sur une grille WebDriver. Si les données se trouvent dans le code HTML initial de la page, ignorez le navigateur et utilisez un client HTTP.

La plupart des équipes utilisaient PhantomJS pour l’une des tâches suivantes. Retrouvez la vôtre dans la colonne de gauche :

Ce que faisait votre script PhantomJS

Utilisez désormais

Pourquoi

Extraction de données sur des pages rendues en JavaScript

Playwright ou Puppeteer

Une version récente de Chromium, avec une fonctionnalité d'attente intégrée, et page.evaluate fonctionne de la même manière

Pages rendues côté serveur et extraites

Un client HTTP associé à un analyseur HTML

Aucun navigateur n’est nécessaire, ce qui rend son exécution plus rapide et moins coûteuse

Captures d'écran

Playwright ou Puppeteer page.screenshot()

Captures d'écran de page entière et d'éléments intégrées

Fichiers PDF générés

Puppeteer page.pdf() ou Playwright page.pdf() (Chromium uniquement)

L'impression au format PDF remplace page.render('file.pdf')

l'exécution des tests unitaires dans Karma

Le lanceur Chrome Headless de Karma à court terme, un exécuteur de tests moderne à long terme

Karma lui-même est obsolète

Exécution des tests Selenium via GhostDriver

Selenium avec Chrome ou Firefox en mode headless

Selenium 4 n'prend plus en charge PhantomJS

Besoin spécifique d’un rendu WebKit

Playwright WebKit

Le moteur le plus proche de QtWebKit de PhantomJS

Exécution de tests Java sans navigateur réel

HtmlUnit

Un navigateur pour Java, maintenu et sans interface graphique

Aucun outil n'a remplacé à lui seul PhantomJS. Les navigateurs modernes disposent désormais d'un véritable mode sans interface graphique, et sont pilotés par un ensemble de bibliothèques. C'est pourquoi il vaut mieux prendre une décision au cas par cas pour chaque script plutôt que d'opter pour une solution unique à l'échelle de l'équipe.

Quelles alternatives à PhantomJS sont encore maintenues ?

Playwright, Puppeteer et Selenium sont activement maintenus et couvrent la quasi-totalité des cas d’utilisation de PhantomJS. Headless Chrome peut également s'exécuter seul depuis la ligne de commande. HtmlUnit est maintenu pour les tests Java sans véritable navigateur. Splash existe toujours pour les utilisateurs de Scrapy, mais est rarement fourni. CasperJS, Zombie.js et PhantomJS lui-même sont archivés.

Outil

Statut

Protocole

Langages

Moteurs

Idéal pour

Playwright

Actif

Protocole Chrome DevTools pour Chromium ; protocoles propres à Playwright pour Firefox et WebKit

JavaScript/TypeScript, Python, Java, .NET

Chromium, Firefox, WebKit

La plupart des nouveaux développements, tests multi-navigateurs, compatibilité avec WebKit

Puppeteer

Actif

Protocole Chrome DevTools ; WebDriver BiDi pour Firefox

JavaScript/TypeScript

Chrome, Firefox

Node.js Automatisation de Chrome, fichiers PDF

Selenium WebDriver

Actif

W3C WebDriver, WebDriver BiDi

Java, Python, C#, Ruby, JavaScript

Tous les principaux navigateurs

Suites de tests existantes, grilles de tests, nombreux langages

Chrome sans interface graphique (CLI)

Actif

Options de ligne de commande ; protocole Chrome DevTools

N'importe quel (shell)

Chrome

Captures d'écran ponctuelles, PDF, vidages DOM

HtmlUnit

Actif (5.6.0, octobre 2026)

En cours de traitement

Java

Moteur propre, pas de rendu

Tests Java sans navigateur

Splash

Faible activité (dernière mise à jour du code en août 2024)

API HTTP et scripts Lua

N'importe quel navigateur (via HTTP)

Basé sur WebKit

Configurations Scrapy existantes

CasperJS, Zombie.js, PhantomJS

Archivé

n/a

n/a

n/a

Migrer vers

Playwright

Playwright est géré par Microsoft et pilote Chromium, Firefox et WebKit via une seule API. Ses localisateurs attendent que les éléments soient attachés, visibles et stables avant d’agir, ce qui élimine la majeure partie du code de synchronisation que comportaient les scripts PhantomJS. Chaque contexte de navigateur est isolé, avec ses propres cookies et son propre espace de stockage, ce qui permet d’exécuter plusieurs sessions au sein d’un même processus de navigateur. Il intègre également un exécuteur de tests avec traçage, captures d’écran en cas d’échec et workers parallèles.

Pour les utilisateurs de PhantomJS, le moteur WebKit est l’élément clé. Si vous avez besoin de reproduire d’anciennes captures d’écran de PhantomJS ou de vérifier comment une page s’affiche dans un moteur de type Safari, lancez webkit au lieu de chromium et ne modifiez pas le reste du script.

Les équipes Python bénéficient de la même API via pip install playwright suivi de playwright install, tandis que les équipes Java peuvent ajouter le com.microsoft.playwright package Maven. Notre guide sur le web scraping avec Playwright aborde les sélecteurs, la pagination et l’exportation de données, et la documentation de Playwright répertorie toutes les API utilisées ci-dessous.

Puppeteer

Puppeteer est maintenu par l’équipe Chrome et est avant tout basé sur Node.js. C’est le portage le plus simple depuis PhantomJS JavaScript, car l’objet de page asynchrone et page.evaluate semble familier, et un script type conserve sa structure. Il gère bien les captures d’écran et la génération de PDF, et il pilote désormais Firefox via WebDriver BiDi en plus de Chrome.

La principale différence entre PhantomJS et Puppeteer réside dans le moteur. Puppeteer pilote une version récente de Chrome, tandis que PhantomJS utilise une version de WebKit datant de 2016. Les pages qui ne s’affichent pas correctement dans PhantomJS en raison de l’utilisation de JavaScript ou de CSS modernes s’affichent généralement correctement dans Puppeteer sans traitement particulier.

Pour un guide complet sur les sélecteurs, la navigation et l’extraction de données, consultez notre guide sur le scraping avec Puppeteer et Node.js. La documentation de Puppeteer couvre les options de lancement, y compris le headless: 'shell' mode décrit ci-dessous.

Selenium WebDriver

Selenium implémente la norme WebDriver du W3C, avec des liaisons officielles pour Java, Python, C#, Ruby et JavaScript. Il prend en charge tous les principaux navigateurs, s’étend à grande échelle via Selenium Grid et intègre désormais WebDriver BiDi pour les événements bidirectionnels tels que les journaux de console et l’activité réseau. Contrairement à Puppeteer, il ne dépend pas du protocole Chrome DevTools pour ses commandes principales. C’est la solution toute indiquée pour les équipes Java et Ruby qui utilisaient PhantomJS, ainsi que pour les suites de tests qui exécutaient PhantomJS via GhostDriver.

Les bibliothèques Python ont déprécié PhantomJS dans la version 3.8.1 et l’ont supprimé dans la version 4.0 Alpha 6 ; webdriver.PhantomJS() n’existent plus. Passez à Chrome ou Firefox avec l’option « headless », et vos localisateurs et assertions continueront de fonctionner. En Java, cela signifie new ChromeOptions().addArguments("--headless=new").

Si vous débutez en Python, consultez notre guide pour créer un scraper Selenium en Python. La documentation Selenium traite des pilotes, des délais d’attente et de la configuration de Grid.

Chrome en mode « headless » seul

Chrome fonctionne en mode « headless » depuis la version 59 en 2017. Depuis la version 112, le mode « headless » correspond au même navigateur que Chrome standard, sans fenêtres visibles. L’ancienne implémentation distincte subsiste sous la forme d’un binaire autonome appelé chrome-headless-shell (depuis Chrome 132), que Puppeteer expose sous le nom de headless: 'shell'.

Les tâches ponctuelles ne nécessitent pas de bibliothèque. Une seule commande remplace un court script PhantomJS :

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

Les options sont documentées dans la documentation du mode sans interface graphique de Chrome. Les lecteurs Python peuvent comparer les options dans notre aperçu des navigateurs sans interface graphique sous Python.

HtmlUnit et Splash

HtmlUnit est un navigateur sans interface graphique destiné aux programmes Java. Il exécute du JavaScript mais n’affiche pas les pixels ; il convient donc aux tests Java qui vérifient la logique des pages et les formulaires, et non aux captures d’écran. Il fait l’objet de mises à jour régulières, la version la plus récente étant la 5.6.0, sortie en octobre 2026.

Splash est un service de rendu scriptable doté d’une API HTTP et de scripts Lua, principalement utilisé via Scrapy-Splash. Il fonctionne toujours pour les équipes qui l’utilisent déjà, mais l’activité de développement est faible depuis 2024. Pour les nouveaux projets de scraping, Playwright est le choix le plus sûr.

Si vous comparez Puppeteer à ses concurrents plutôt que de remplacer PhantomJS, consultez notre comparatif des alternatives à Puppeteer.

Comment les commandes de PhantomJS se traduisent-elles dans Playwright et Puppeteer ?

La plupart des appels PhantomJS ont un équivalent direct à la fois dans Playwright et dans Puppeteer ; la conversion se résume donc principalement à un changement de nom. page.open devient page.goto, page.render devient page.screenshot ou page.pdf, page.evaluate conserve son nom, et les callbacks deviennent async/await. Le véritable changement concerne l’attente. Remplacez les délais d’attente fixes par des attentes basées sur un sélecteur ou l’état de chargement.

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') avec page.paperSize

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

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) et page.on('request', …)

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

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

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

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

await page.locator(sel).click()

await page.click(sel)

setTimeout attend / page.onLoadFinished

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

await page.waitForSelector(sel)

--proxy=host:port indicateur de ligne de commande

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()

Deux lignes ont été modifiées dans les dernières versions de Puppeteer. Les cookies sont désormais stockés dans le navigateur ou le contexte du navigateur (browser.setCookie), les méthodes de cookies au niveau de la page étant désormais obsolètes. De plus, setUserAgent prend en paramètre un objet d’options. Les anciens tutoriels qui appellent page.setCookie fonctionnent toujours, mais affichent des avertissements de dépréciation.

Avant : un script PhantomJS

Ce script ouvre la boutique d’entraînement « Books to Scrape », lit le titre de la page et les cinq premiers liens vers des livres, enregistre une capture d’écran, puis se ferme :

// 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();
});

Après : le même script dans Playwright

Installez Playwright avec npm install playwright et npx playwright install chromium, puis exécutez le port en tant que module ES :

// 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();
}

Les deux scripts affichent les mêmes données :

{
  "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"
    }
  ]
}

La structure ne change pratiquement pas. La fonction de rappel devient une variable de niveau supérieur await, try/finally remplace les appels dispersés phantom.exit() appels épars, de sorte que le navigateur se ferme toujours, et une attente explicite sur les fiches produits remplace l’espoir que page.open soit déclenché suffisamment tard. La fonction que vous passez à page.evaluate s'exécute toujours à l'intérieur de la page ; votre code DOM est donc transféré tel quel, et vous pouvez supprimer les solutions de contournement ES5 telles que Array.prototype.slice.call.

Pour utiliser Puppeteer à la place, importez puppeteer, appelez puppeteer.launch(), définissez la fenêtre d’affichage avec page.setViewport(), puis remplacez l'attente du localisateur par page.waitForSelector('article.product_pod'). Tout le reste reste inchangé.

Comment migrer un script PhantomJS étape par étape ?

Faites l’inventaire de ce que fait chaque script, puis choisissez le remplacement adapté à chaque tâche. Installez Playwright ou Puppeteer, et portez les appels à l’aide de la table de correspondance. Remplacez les temps d’attente fixes par des attentes de sélecteur, puis comparez les résultats aux anciennes captures d’écran ou données. Enfin, supprimez les binaires PhantomJS et les paquets wrapper de vos dépendances, images CI et fichiers Dockerfile.

  1. Inventaire. Recherchez dans la base de code phantomjs, require('webpage'), casper, GhostDriver, et karma-phantomjs-launcher. Vérifiez également les configurations CI et les fichiers Dockerfile, car PhantomJS se cache souvent dans une étape de build plutôt que dans le code de l’application.
  2. Classez chaque script par tâche. Utilisez le tableau de sélection rapide ci-dessus. Une tâche de capture d’écran et une suite Selenium nécessitent des solutions de remplacement différentes, même au sein d’un même dépôt.
  3. Installez la solution de remplacement. Playwright télécharge ses propres versions de navigateur avec npx playwright install, la CI doit donc inclure cette étape ou utiliser l’image Docker officielle. Les équipes Python utilisent pip install playwright et playwright install à la place.
  4. Portez les appels. Suivez le tableau de mappage. Les callbacks deviennent async/await, et les propriétés des gestionnaires d’événements telles que page.onConsoleMessage deviennent page.on(...) des « listeners ».
  5. Corrigez les attentes. C’est la source de différences la plus courante après une migration. Remplacez chaque setTimeout et onLoadFinished par une attente de l’élément ou de l’état de chargement dont vous avez réellement besoin.
  6. Comparez les résultats. Comparez le code HTML, les données extraites ou les captures d’écran avec ceux obtenus lors d’une exécution sous PhantomJS. Attendez-vous à quelques différences de rendu, car le nouveau moteur prend en charge les polices, la mise en page et le CSS que WebKit de 2016 ne prenait pas en charge.
  7. Mettez à jour l’intégration continue (CI) et les conteneurs. Installez les bibliothèques système requises par le nouveau navigateur, puis supprimez le binaire PhantomJS et toutes les OPENSSL_CONF ou solutions de contournement fontconfig que vous aviez ajoutées pour celui-ci.
  8. Supprimez les résidus. Supprimez les anciens paquets et lanceurs, comme expliqué ci-après.

Qu’est-ce qui remplace karma-phantomjs-launcher, phantomjs-prebuilt et GhostDriver ?

Remplacez karma-phantomjs-launcher par le lanceur Chrome Headless de Karma, puis prévoyez de migrer hors de Karma, qui est lui-même obsolète. Supprimez phantomjs-prebuilt, que npm marque comme obsolète, et portez ses scripts vers Playwright ou Puppeteer. Remplacez les sessions GhostDriver par les pilotes Chrome ou Firefox de Selenium en mode headless, puisque Selenium 4 a supprimé PhantomJS.

C'est dans ces vestiges que PhantomJS survit généralement le plus longtemps, car il se trouve dans des outils de test et d'automatisation des navigateurs que personne ne touche jusqu'à ce qu'une compilation échoue.

Karma. Le dépôt karma-phantomjs-launcher a été archivé après sa dernière activité en 2017. La solution rapide consiste à installer karma-chrome-launcher et de configurer browsers: ['ChromeHeadless'] dans karma.conf.js. Cela permet de maintenir la suite au vert, mais Karma constitue le problème le plus important. L’avis de dépréciation de Karma indique qu’il n’accepte plus de nouvelles fonctionnalités ni de corrections de bogues générales. Angular a ajouté Jest et Web Test Runner comme voies de migration, et l’un ou l’autre convient aux tests unitaires qui s’exécutaient auparavant sous PhantomJS.

Paquets npm. phantomjs-prebuilt (dernière version 2.1.16) est marqué sur npm comme « ce paquet est désormais obsolète », et l’ancien phantomjs renvoie vers celui-ci. Les deux téléchargent le binaire 2.1.1, qui n’est plus maintenu. Supprimez-les avec npm uninstall phantomjs-prebuilt phantomjs, puis vérifiez votre fichier de verrouillage, car d’autres dépendances de développement les intègrent parfois.

Selenium et GhostDriver. DesiredCapabilities.PHANTOMJS et webdriver.PhantomJS() ont disparu de Selenium 4. En Python, le remplacement ne nécessite que trois lignes :

from selenium import webdriver

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

Selenium Manager recherche ou télécharge un pilote compatible, vous n’avez donc plus besoin de fournir un binaire GhostDriver séparé. Firefox fonctionne de la même manière avec FirefoxOptions et l’ -headless argument.

Images Docker. Supprimez toute apt-get install phantomjs ou toute installation globale de PhantomJS via npm. Utilisez l’image officielle de Playwright, ou suivez les recommandations de Puppeteer concernant les bibliothèques système dont Chrome a besoin dans un conteneur.

Avez-vous vraiment besoin d’un navigateur sans interface graphique ?

Souvent, non. De nombreux scrapers PhantomJS ont été écrits à une époque où le rendu semblait plus sûr, mais si les données se trouvent déjà dans le code HTML initial de la page ou dans un point de terminaison JSON, un client HTTP associé à un analyseur syntaxique est plus rapide et plus simple. Vérifiez d’abord le code source de la page et n’utilisez un navigateur que lorsque le contenu s’affiche après l’exécution de JavaScript.

Une vérification rapide ne prend qu’une minute :

  1. Ouvrez la page et affichez sa source, et non le DOM inspecté.
  2. Recherchez dans la source la valeur que vous souhaitez extraire, comme un prix ou un nom de produit.
  3. Si elle n’y figure pas, ouvrez l’onglet « Réseau » dans les outils de développement de votre navigateur et recherchez les requêtes XHR ou fetch qui renvoient du JSON.

Si l’étape 2 permet de trouver la valeur, une simple requête HTTP et un analyseur syntaxique permettent de l’obtenir en un temps et avec une consommation de mémoire bien inférieurs à ceux d’un navigateur. Si l’étape 3 identifie un point de terminaison JSON, appelez-le directement et évitez également l’analyse du code HTML. Notre comparaison entre Cheerio et Puppeteer présente les deux approches côte à côte sous Node.js.

Réservez le navigateur aux tâches qui en nécessitent un : parcours de flux, connexion, défilement infini, captures d’écran, fichiers PDF et tests visuels.

Quand faut-il cesser d’exécuter soi-même des navigateurs ?

Cessez l’auto-hébergement lorsque la maintenance des navigateurs coûte plus cher que ce que rapportent les scripts. Les signes courants sont les plantages et les fuites de mémoire à grande échelle, la dérive des versions de navigateur en CI, les requêtes bloquées et la nécessité de vérifier les pages depuis plusieurs pays et appareils. Une API gérée exécute le navigateur et renvoie du code HTML, des données ou des captures d’écran via des requêtes HTTP simples.

Gérer un seul navigateur sans interface utilisateur est facile. En gérer des centaines, c’est une autre histoire. Vous devez gérer les limites de concurrence, nettoyer les processus Chrome qui ne se ferment jamais, synchroniser les versions des navigateurs entre les ordinateurs portables des développeurs et l’environnement d’intégration continue (CI), et gérer les sites qui bloquent le trafic vers les centres de données. Si vous avez besoin de voir une page telle que la voient les visiteurs d’un autre pays, vous avez également besoin d’une infrastructure dans ce pays.

L’API navigateur de WebScrapingAPI décharge vos serveurs de cette tâche. Vous envoyez une URL avec des délais d’attente, par exemple wait_until ou wait_for_css, ainsi que des actions sur la page, telles que cliquer, faire défiler, saisir du texte, sélectionner et valider. Elle renvoie le code HTML rendu, un DOM au format JSON, les champs extraits ou une capture d’écran en base64. Il s’agit d’une interface REST de type requête-réponse sans session de navigateur active ; vous n’avez donc pas besoin d’y associer Puppeteer ou Playwright. Vous décrivez les étapes dans la requête et recevez le résultat.

Pour les tâches de capture d’écran et d’assurance qualité souvent prises en charge par PhantomJS, notre solution de test de sites web sur tous les marchés et tous les appareils vérifie les pages publiques par pays, par appareil et par fenêtre d’affichage, et conserve des captures d’écran à titre de preuve.

Si vous n’avez besoin que du code HTML rendu, comparez les API d’accès au Web pour trouver celle qui correspond le mieux à vos besoins.

FAQ

L'utilisation de PhantomJS est-elle toujours sûre ?

Pas pour les pages non fiables. PhantomJS n’a pas bénéficié de correctifs de sécurité depuis la suspension de son développement en 2018, et la vulnérabilité CVE-2019-17221 permet à une page de lire des fichiers locaux page.open() en l’absence de version corrigée. Si vous devez le conserver temporairement, utilisez-le uniquement sur des pages que vous contrôlez, dans un conteneur isolé, le temps de la migration.

Puis-je encore installer PhantomJS depuis npm ?

C'est possible, mais déconseillé. Le phantomjs-prebuilt paquet est marqué comme obsolète sur npm, et ses binaires correspondent à la version 2.1.1, qui n’est plus maintenue. Pour les nouveaux projets, il est préférable d’installer Playwright ou Puppeteer à la place. Ces deux outils téléchargent une version récente du navigateur et bénéficient de mainteneurs actifs ainsi que d’une documentation à jour.

Quel est le meilleur choix entre Playwright et Puppeteer pour remplacer PhantomJS ?

Playwright convient à la plupart des équipes. Il prend en charge Chromium, Firefox et WebKit, dispose de liaisons Python, Java et .NET, et attend automatiquement les éléments. Puppeteer est un bon choix pour les projets Node qui n’ont besoin que de Chrome, ou pour la génération de PDF. Les deux permettent de porter les scripts PhantomJS avec un effort similaire, car page.evaluate fonctionnent de la même manière.

Selenium prend-il toujours en charge PhantomJS ?

Non. Selenium a déprécié PhantomJS dans la version 3.8.1 et l’a supprimé dans Selenium 4 ; par conséquent, webdriver.PhantomJS() les sessions PhantomJS et GhostDriver ne fonctionnent plus. Remplacez ces tests par Chrome ou Firefox avec l’option « headless ». Vos localisateurs et assertions WebDriver restent pour la plupart inchangés, le portage est donc généralement minime.

Qu'est-ce qui a remplacé PhantomJS dans Karma ?

Le lanceur Chrome Headless de Karma est généralement utilisé pour remplacer directement karma-phantomjs-launcher. Karma lui-même est toutefois désormais obsolète. Pour une solution à plus long terme, transférez vos tests unitaires vers un exécuteur maintenu, tel que Jest ou Web Test Runner, qu’Angular a ajoutés comme chemins de migration.

Quelle alternative à PhantomJS utilise WebKit ?

Playwright. Il intègre une version de WebKit en plus de Chromium et Firefox, ce qui en fait le moteur de rendu le plus proche du moteur QtWebKit de PhantomJS. Utilisez-le lorsque vous avez besoin de reproduire d’anciennes captures d’écran de PhantomJS ou de tester un rendu de type Safari. Pour tout le reste, Chromium est la valeur par défaut courante.

Quelle alternative à PhantomJS choisir ?

Faites votre choix en fonction de la tâche à accomplir. Utilisez Playwright pour la plupart des opérations de scraping, de captures d’écran et de tests multi-navigateurs, Puppeteer pour l’automatisation de Chrome sous Node.js et les fichiers PDF, et Selenium pour les suites WebDriver existantes, quel que soit le langage. Avant de porter un scraper, vérifiez si les données se trouvent déjà dans le code HTML, car le navigateur le plus rapide est celui que vous n’utilisez pas. Supprimez ensuite les binaires, les wrappers et les lanceurs de PhantomJS afin que rien ne réintroduise l’ancien moteur dans vos builds.

Évitez la maintenance des navigateurs

Affichez des pages JavaScript sans lancer de navigateur. Envoyez une URL à l’API Scraper et récupérez le code HTML affiché. Commencez avec 5 000 requêtes gratuites. L’affichage JavaScript et le ciblage géographique ne coûtent pas de crédits supplémentaires, et les requêtes ayant échoué ne sont pas facturées.

Découvrez l’API Scraper

À propos de l'auteur

Sorin-Gabriel Marica, Développeur full-stack @ WebScrapingAPI

Sorin-Gabriel Marica

Développeur full-stack

Sorin Marica est ingénieur Full Stack et DevOps chez WebScrapingAPI ; il développe des fonctionnalités pour les produits et assure la maintenance de l'infrastructure qui garantit le bon fonctionnement de la plateforme.

Web scraping avec AWS Lambda : guide pour Python et Java 2026
Guides

Web scraping avec AWS Lambda : guide pour Python et Java 2026

TL;DR: En bref : le web scraping avec AWS Lambda fonctionne mieux lorsque chaque invocation est courte, bien délimitée et peut faire l'objet d'une nouvelle tentative de manière indépendante. Commencez par utiliser les requêtes HTTP directes, AWS SAM et S3, puis ajoutez SQS, des conteneurs, le rendu dans un navigateur, des proxys ou une couche de récupération gérée uniquement lorsque la charge de travail démontre qu'elle en a besoin.

Suciu Dan33 min read
Lire l'article
Comment utiliser GoSpider : exploration, nettoyage des URL et extraction de données
Guides

Comment utiliser GoSpider : exploration, nettoyage des URL et extraction de données

TL;DR: En bref : GoSpider est un robot d'exploration en ligne de commande destiné à découvrir des URL, et non un outil complet de collecte de données structurées. Ce guide d'utilisation de GoSpider présente comment effectuer une exploration limitée, gérer correctement les résultats, transférer les données de Colly vers un fichier CSV, ainsi qu'une procédure de diagnostic pour les réponses 403 ou les pages nécessitant un rendu JavaScript.

Suciu Dan24 min read
Lire l'article
Comment récupérer les données de Redfin : Guide Python des données immobilières
Guides

Comment récupérer les données de Redfin : Guide Python des données immobilières

TL;DR: Redfin expose des points d'extrémité d'API cachés qui renvoient du JSON structuré pour les listes de propriétés, ce qui permet d'ignorer complètement l'analyse HTML fragile. Ce guide vous accompagne dans la construction d'un scraper Python qui extrait les données de location et de vente, effectue des recherches par emplacement, surveille les nouvelles inscriptions via des sitemaps XML et exporte des résultats propres au format CSV ou JSON.

Suciu Dan15 min read
Lire l'article

Commencez à créer

Prêt à faire évoluer votre système de collecte de données ?

Rejoignez plus de 2 000 entreprises qui utilisent WebScrapingAPI pour extraire des données Web à l'échelle de l'entreprise, sans aucun coût d'infrastructure.