Comment gérer un "pool" de PhantomJS instances
Je suis la planification d'un webservice pour ma propre utilisation en interne qui prend un argument, une URL et retourne html représentant le résolu DOM à partir de cette URL. Par résolu, je veux dire que le webservice d'abord obtenir la page à l'URL, puis utilisez PhantomJS pour "restituer" la page, et ensuite de retour à l'résultant de la source après tout, DHTML, AJAX appels, etc sont exécutées. Cependant le lancement de fantôme sur une demande de base (dont je fais maintenant) est façon trop lent. Je préférerais avoir un pool de PhantomJS cas, avec une toujours disponible pour servir le dernier appel à mon webservice.
A aucun travail sur ce genre de chose avant? Je préfère la base de ce webservice sur le travail des autres que d'écrire un gestionnaire de pool /serveur proxy http pour moi-même à partir de zéro.
Plus de Contexte: j'ai listé les 2 projets similaires que j'ai vu jusqu'à présent ci-dessous et pourquoi j'ai évité de chacun, ce qui entraîne dans cette question à propos de la gestion d'un pool de PhantomJS instances de la place.
jsdom - de ce que j'ai vu il a une grande fonctionnalité pour l'exécution de scripts sur une page, mais il ne tente pas de reproduire le comportement du navigateur, donc, si je devais l'utiliser comme un objectif général de "DOM " resolver" il y aurait finissent par être beaucoup de codage supplémentaire pour gérer tous les types de bords des cas, l'appel, etc. Le premier exemple que j'ai vu était manuellement l'appel de la onload() fonction de la balise body pour une application de test j'ai configuré l'aide d'un noeud. Il semblait que le début d'un profond trou de lapin.
Sélénium - Il a juste soo beaucoup plus de pièces mobiles, de sorte que la configuration d'un pool de gérer longue durée de vie instances de navigateur en sera que plus compliqué que d'utiliser PhantomJS. Je n'ai pas besoin de c'est l'enregistrement de la macro /script avantages. Je veux juste un webservice qui est aussi performant à obtenir une page web et de le résoudre DOM comme si j'étais la navigation vers cette URL dans un navigateur (ou même plus vite, si je peux le faire ignorer les images etc.)
Vous devez vous connecter pour publier un commentaire.
J'ai installé une PhantomJs Service de Cloud computing, et il a à peu près fait ce que vous demandez. Il m'a fallu environ 5 semaines de travail à mettre en œuvre.
Le plus grand problème que vous rencontrerez dans l'est connu que le problème de les fuites de mémoire dans PhantomJs. La façon dont j'ai travaillé autour de ce est le cycle de mon cas tous les 50 appels.
Le deuxième plus grand problème que vous rencontrerez dans l'est par le traitement de la page est très cpu et de la mémoire intensive, donc vous aurez seulement être en mesure d'exécuter 4 cas par UC.
Le troisième plus grand problème que vous rencontrerez dans l'est que PhantomJs est assez loufoque avec page-finition des événements et des redirections. Vous serez informé que votre page est rendu terminé avant qu'il ne l'est réellement. Il y a un certain nombre de façons de traiter ce, mais rien de "standard" malheureusement.
Le quatrième plus grand problème que vous aurez à traiter est de l'interopérabilité entre nodejs et phantomjs heureusement, il y a beaucoup de packages npm qui traitent de cette question à choisir.
Donc je sais que je suis partial (comme je l'ai écrit la solution que je vais proposer), mais je vous suggère de vérifier PhantomJsCloud.com qui est gratuit pour une utilisation faible.
Jan 2015 mise à jour: un Autre (5ème?) gros problème que j'ai rencontré est de savoir comment envoyer la demande/réponse de la part du gestionnaire/load-balancer. À l'origine, j'ai été en utilisant PhantomJS est le serveur HTTP intégré, mais restent en cours d'exécution dans ses limites, en particulier au sujet de la réponse maximale de la taille. J'ai fini par écrire la requête/réponse pour le système de fichiers local, comme les lignes de communication. * Temps Total passé sur la mise en œuvre du service, constitue peut-être 20 semaines-homme questions est peut-être 1000 heures de travail. * et pour info je suis en train de faire une réécriture complète pour la prochaine version.... (en cours)
La async bibliothèque JavaScript travaille dans le Nœud et a un
queue
fonction qui est très pratique pour ce genre de chose:Certains pseudo-code:
Découvrez la toute la documentation de
file
dans le readme du projet.async.queue
fonction n'est assurez-vous que pas plus qu'un certain nombre d'appels à la fonction sont en circulation à un moment donné; ce que vous faites à l'intérieur de cette fonction est à vous.Pour mon maître de thèse, j'ai développé la bibliothèque phantomjs-piscine qui fait exactement cela. Il permet de fournir des emplois qui sont ensuite cartographiés à PhantomJS travailleurs. La bibliothèque gère la distribution des tâches, la communication, la gestion des erreurs, l'exploitation forestière, le redémarrage et quelques autres trucs. La bibliothèque a été utilisée avec succès pour analyser plus d'un million de pages.
Exemple:
Le code suivant exécute une recherche Google pour les nombres de 0 à 9 et enregistre une capture d'écran de la page comme googleX.png. Quatre sites sont analysées en parallèle (en raison de la création de quatre travailleurs). Le script est lancé via
node master.js
.master.js (fonctionne dans le Node.js de l'environnement)
worker.js (fonctionne dans le PhantomJS environnement)
pool.start()
de faire quelque chose une fois une série de processus est terminé?Comme une alternative à @JasonS grande réponse, vous pouvez essayer PhearJS, que j'ai construit. PhearJS est un superviseur de l'écrit en NodeJS pour PhantomJS instances et fournit une API via HTTP. Il est disponible en open-source de Github.
si vous utilisez nodejs pourquoi ne pas utiliser le sélénium, le webdriver
phantomjs --webdriver=port_number
pour chaque phantomjs exemple créer PhantomInstance
et mettez-les tous dans un tableau [phantomInstance1,phantomInstance2]
créer dispather.js que obtenez gratuitement phantomInstance de la matrice et
Si vous utilisez nodejs, vous pouvez utiliser https://github.com/sgentle/phantomjs-node, qui va vous permettre de connecter un nombre arbitraire de phantomjs processus de votre principal NodeJS, d'où, la possibilité d'utiliser async.js et beaucoup de nœud goodies.