Pour mon boulot, j’ai eu besoin d’utiliser PhantomJS afin de récupérer une page web. L’idée était de générer une page web dont une grande partie est récupérée au load de la page en javascript, et d’envoyer cette page générée aux moteurs de recherches (problématiques SEO). Ou tout du moins, dans un premier temps, de parvenir à générer cette page web.
Je mets donc ci-dessous les pages qui m’ont servies.
Installer PhantomJS sur Windows (via)
- Télécharger PhantomJS sur le site (ici)
- Décompresser
phantomjs-x.y.z-windows.zip
et le copier/coller là où vous voudrez, par exemple dansC:\Program Files (x86)\PhantomJS\phantomjs-x.y.z-windows
- Ajouter à la variable
PATH
le chemin vers l’exécutable de PhantomJS :C:\Program Files (x86)\PhantomJS\phantomjs-x.y.z-windows
(la variablePATH
se trouve dansPanneau de configuration\Système et sécurité\Système > Modifier les paramètres > Onglet Paramètres système avancés > Variables d'environnement
) - Ouvrir une commande (
cmd
) et taperphantomjs --version
L’authentification par HTACCESS
Concernant l’authentification sur un htaccess, cette page explique comment faire. En gros, il faut rajouter ça en haut :
page.settings.userName = 'myUserName'; page.settings.password = 'myPassword'; page.customHeaders={'Authorization': 'Basic '+btoa('username:password')};
Le code final pour appeler ma page (via) :
var system = require('system'), fs = require('fs'), page = new WebPage(), url = system.args[1], output = system.args[2], result; page.settings.userName = 'myUserName'; page.settings.password = 'myPassword'; page.customHeaders={'Authorization': 'Basic '+btoa('username:password')}; page.open(url, function (status) { if (status !== 'success') { console.log('FAILED to load the url'); phantom.exit(); } else { result = page.evaluate(function(){ var html, doc; html = document.querySelector('html'); return html.outerHTML; }); if(output){ var rendered = fs.open(output,'w'); rendered.write(result); rendered.flush(); rendered.close(); }else{ console.log(result); } } phantom.exit(); });
Pourquoi ça s’est mal fini
J’ai eu une première erreur, ne bloquant pas la création de la page :
C:\Program Files (x86)\PhantomJS\phantomjs-1.9.7-windows\examples>phantomjs perso_exemple.js https://mon_url.fr/home mon_fichier_final.html TypeError: 'null' is not an object (evaluating 'body.querySelector('div#title-block').style') phantomjs://webpage.evaluate():4 phantomjs://webpage.evaluate():6 phantomjs://webpage.evaluate():6
Je n’ai pas trouvé comment la résoudre, mais globalement ça ne me gênait pas trop car j’avais mon résultat.
Le problème du moteur JS
La dernière erreur, par contre, m’a stoppé, et m’a contraint d’aller vers un autre navigateur en ligne de commande. :
C:\Program Files (x86)\PhantomJS\phantomjs-1.9.7-windows\examples>phantomjs perso_exemple.js https://mon_url.fr/home mon_fichier_final.html TypeError: 'undefined' is not a function (evaluating 'MyLib.SubLib.toggleBar()') https://mon_url.fr/static/mes_libs_javascript.js:141
En effet, il semble que PhantomJS n’utilise pas le compiler V8 que l’on retrouve dans Chrome. Dommage car du coup son compilateur est beaucoup moins permissif (ou plus con). Donc du coup, il s’attendait à ce qu’une méthode appelée au sein d’une function JS ait été définit plus haut. Hérésie (notamment lorsque c’est dans la méthode init() que l’appel à une autre méthode était fait, alors que l’autre méthode était définie juste en dessous).
Sur cette page, il semble que PhantomJS utilise le moteur JS JavascriptCore.
But, PhantomJS uses JavaScriptCore with JIT compiler as its Javascript engine. Instead, I want to use the V8 engine, which is used in Google Chrome, or Chakra, which is used in IE. I want to do this because I want to check platform compatibility for the code.
La personne qui répond conseille d’utiliser ZombieJS (pour utiliser V8), ou SlimerJS (pour utiliser le moteur de rendu Gecko, mais je ne sais pas quel est le moteur JS derrière).