J'utilise PhantomJS v1.4.1 pour charger certaines pages Web. Je n'ai pas accès à leur côté serveur, je reçois juste des liens pointant vers eux. J'utilise une version obsolète de Phantom car je dois prendre en charge Adobe Flash sur ces pages Web.
Le problème est que de nombreux sites Web chargent leur contenu mineur de manière asynchrone et c'est pourquoi le rappel onLoadFinished de Phantom (analogique pour onLoad en HTML) est déclenché trop tôt alors que tout n'est pas encore chargé. Quelqu'un peut-il suggérer comment puis-je attendre le chargement complet d'une page Web pour faire, par exemple, une capture d'écran avec tout le contenu dynamique comme les publicités?
javascript
events
phantomjs
nilfalse
la source
la source
Réponses:
Une autre approche consiste simplement à demander à PhantomJS d'attendre un peu après le chargement de la page avant de faire le rendu, comme dans l' exemple habituel de rasterize.js , mais avec un délai d'expiration plus long pour permettre au JavaScript de terminer le chargement de ressources supplémentaires:
la source
Je préfère vérifier périodiquement le
document.readyState
statut ( https://developer.mozilla.org/en-US/docs/Web/API/document.readyState ). Bien que cette approche soit un peu maladroite, vous pouvez être sûr qu'à l'intérieur de laonPageReady
fonction vous utilisez un document entièrement chargé.Explication supplémentaire:
Utiliser nested
setTimeout
au lieu desetInterval
empêche lecheckReadyState
"chevauchement" et les conditions de concurrence lorsque son exécution est prolongée pour des raisons aléatoires.setTimeout
a un délai par défaut de 4 ms ( https://stackoverflow.com/a/3580085/1011156 ) de sorte que l'interrogation active n'affectera pas considérablement les performances du programme.document.readyState === "complete"
signifie que le document est complètement chargé avec toutes les ressources ( https://html.spec.whatwg.org/multipage/dom.html#current-document-readiness ).la source
readyState
ne se déclenchera qu'une fois le DOM complètement chargé, mais tous les<iframe>
éléments peuvent encore être en cours de chargement, donc cela ne répond pas vraiment à la question d'origineVous pouvez essayer une combinaison des exemples d'attente et de pixellisation:
la source
Vous pouvez peut-être utiliser les rappels
onResourceRequested
etonResourceReceived
pour détecter le chargement asynchrone. Voici un exemple d'utilisation de ces rappels de leur documentation :Vous pouvez également consulter
examples/netsniff.js
un exemple de travail.la source
All the resource requests and responses can be sniffed using onResourceRequested and onResourceReceived
Voici une solution qui attend que toutes les demandes de ressources se terminent. Une fois terminé, il enregistrera le contenu de la page sur la console et générera une capture d'écran de la page rendue.
Bien que cette solution puisse servir de bon point de départ, j'ai constaté qu'elle échouait donc ce n'est certainement pas une solution complète!
Je n'ai pas eu beaucoup de chance d'utiliser
document.readyState
.J'ai été influencé par l' exemple waitfor.js trouvé sur la page d'exemples phantomjs .
la source
Dans mon programme, j'utilise une logique pour juger s'il était en charge: en regardant sa requête réseau, s'il n'y avait pas de nouvelle requête sur les 200 ms passés, je la traite en charge.
Utilisez ceci, après onLoadFinish ().
la source
J'ai trouvé cette approche utile dans certains cas:
Que si vous possédez la page, mettez un script à l'intérieur:
la source
J'ai trouvé cette solution utile dans une application NodeJS. Je l'utilise juste dans des cas désespérés car il lance un délai d'attente pour attendre le chargement complet de la page.
Le deuxième argument est la fonction de rappel qui sera appelée une fois que la réponse sera prête.
la source
Ceci est une implémentation de la réponse de Supr. Il utilise également setTimeout au lieu de setInterval comme le suggérait Mateusz Charytoniuk.
Phantomjs se fermera dans 1000 ms lorsqu'il n'y aura aucune demande ou réponse.
la source
Voici le code que j'utilise:
Fondamentalement, étant donné que vous êtes censé savoir que la page est entièrement téléchargée lorsqu'un élément donné apparaît sur le DOM. Le script va donc attendre que cela se produise.
la source
J'utilise un mélange personnel de l'
waitfor.js
exemple phantomjs .Voici mon
main.js
dossier:Et le
lib/waitFor.js
fichier (qui est juste un copier-coller de lawaifFor()
fonction de l'waitfor.js
exemple phantomjs ):Cette méthode n'est pas asynchrone mais au moins suis-je assuré que toutes les ressources ont été chargées avant que j'essaye de les utiliser.
la source
C'est une vieille question, mais comme je cherchais un chargement complet de la page mais pour Spookyjs (qui utilise casperjs et phantomjs) et que je n'ai pas trouvé ma solution, j'ai créé mon propre script pour cela, avec la même approche que l'utilisateur estime. Ce que fait cette approche, c'est que, pendant une durée donnée, si la page n'a pas reçu ou commencé une demande, elle mettra fin à l'exécution.
Sur le fichier casper.js (si vous l'avez installé globalement, le chemin serait quelque chose comme /usr/local/lib/node_modules/casperjs/modules/casper.js) ajoutez les lignes suivantes:
En haut du fichier avec toutes les variables globales:
Puis à l'intérieur de la fonction "createPage (casper)" juste après "var page = require ('webpage'). Create ();" ajoutez le code suivant:
Puis à l'intérieur de "page.onResourceReceived = function onResourceReceived (resource) {" sur la première ligne, ajoutez:
Faites de même pour "page.onResourceRequested = function onResourceRequested (requestData, request) {"
Enfin, sur "page.onLoadFinished = function onLoadFinished (status) {" sur la première ligne, ajoutez:
Et c'est tout, j'espère que celui-ci aidera quelqu'un en difficulté comme moi. Cette solution est pour casperjs mais fonctionne directement pour Spooky.
Bonne chance !
la source
c'est ma solution son a fonctionné pour moi.
la source