Estoy usando PhantomJS v1.4.1 para cargar algunas páginas web. No tengo acceso a su lado del servidor, solo obtengo enlaces que apuntan a ellos. Estoy usando una versión obsoleta de Phantom porque necesito admitir Adobe Flash en esas páginas web.
El problema es que muchos sitios web están cargando su contenido asíncrono menor y es por eso que la devolución de llamada onLoadFinished de Phantom (análogo para onLoad en HTML) se activó demasiado temprano cuando aún no se ha cargado todo. ¿Alguien puede sugerir cómo puedo esperar la carga completa de una página web para hacer, por ejemplo, una captura de pantalla con todo el contenido dinámico como los anuncios?
javascript
events
phantomjs
nilfalse
fuente
fuente
Respuestas:
Otro enfoque es simplemente pedirle a PhantomJS que espere un poco después de que la página se haya cargado antes de realizar el renderizado, según el ejemplo regular rasterize.js , pero con un tiempo de espera más largo para permitir que JavaScript termine de cargar recursos adicionales:
fuente
Prefiero verificar periódicamente el
document.readyState
estado ( https://developer.mozilla.org/en-US/docs/Web/API/document.readyState ). Aunque este enfoque es un poco torpe, puede estar seguro de que laonPageReady
función interna está utilizando un documento completamente cargado.Explicación adicional:
El uso de anidado en
setTimeout
lugar desetInterval
evita lacheckReadyState
"superposición" y las condiciones de carrera cuando su ejecución se prolonga por algunas razones aleatorias.setTimeout
tiene un retraso predeterminado de 4 ms ( https://stackoverflow.com/a/3580085/1011156 ), por lo que el sondeo activo no afectará drásticamente el rendimiento del programa.document.readyState === "complete"
significa que el documento está completamente cargado con todos los recursos ( https://html.spec.whatwg.org/multipage/dom.html#current-document-readiness ).fuente
readyState
será único desencadenante una vez que el DOM se ha cargado completamente, sin embargo ningún<iframe>
elementos todavía puede ser de carga por lo que en realidad no contesta la pregunta originalPuede probar una combinación de los ejemplos waitfor y rasterize:
fuente
Tal vez pueda usar las devoluciones de llamada
onResourceRequested
yonResourceReceived
para detectar la carga asincrónica. Aquí hay un ejemplo del uso de esas devoluciones de llamada de su documentación :Además, puede buscar
examples/netsniff.js
un ejemplo de trabajo.fuente
All the resource requests and responses can be sniffed using onResourceRequested and onResourceReceived
Aquí hay una solución que espera a que se completen todas las solicitudes de recursos. Una vez completado, registrará el contenido de la página en la consola y generará una captura de pantalla de la página renderizada.
Aunque esta solución puede servir como un buen punto de partida, he observado que falla, por lo que definitivamente no es una solución completa.
No tuve mucha suerte usando
document.readyState
.Fui influenciado por el ejemplo waitfor.js que se encuentra en la página de ejemplos phantomjs .
fuente
En mi programa, uso algo de lógica para juzgar si estaba en carga: viendo su solicitud de red, si no hubo una nueva solicitud en los últimos 200 ms, la trato como en carga.
Use esto, después de onLoadFinish ().
fuente
Encontré este enfoque útil en algunos casos:
Que si usted es dueño de la página, coloque algún script dentro:
fuente
Encontré esta solución útil en una aplicación NodeJS. Lo uso solo en casos desesperados porque inicia un tiempo de espera para esperar la carga de la página completa.
El segundo argumento es la función de devolución de llamada que se llamará una vez que la respuesta esté lista.
fuente
Esta es una implementación de la respuesta de Supr. También usa setTimeout en lugar de setInterval como lo sugirió Mateusz Charytoniuk.
Phantomjs saldrá en 1000 ms cuando no haya ninguna solicitud o respuesta.
fuente
Este es el código que uso:
Básicamente, dado el hecho de que se supone que debes saber que la página se descarga por completo cuando aparece un elemento determinado en el DOM. Entonces el guión esperará hasta que esto suceda.
fuente
Utilizo una mezcla personal del
waitfor.js
ejemplo phantomjs .Este es mi
main.js
archivo:Y el
lib/waitFor.js
archivo (que es solo una copia y pega de lawaifFor()
función delwaitfor.js
ejemplo phantomjs ):Este método no es asíncrono, pero al menos estoy seguro de que todos los recursos se cargaron antes de intentar usarlos.
fuente
Esta es una vieja pregunta, pero como estaba buscando la carga de la página completa, pero para Spookyjs (que usa casperjs y phantomjs) y no encontré mi solución, creé mi propio script para eso, con el mismo enfoque que el usuario deemstone. Lo que hace este enfoque es que, durante un período de tiempo determinado, si la página no recibió o inició alguna solicitud, finalizará la ejecución.
En el archivo casper.js (si lo instaló globalmente, la ruta sería algo así como /usr/local/lib/node_modules/casperjs/modules/casper.js) agregue las siguientes líneas:
En la parte superior del archivo con todos los vars globales:
Luego dentro de la función "createPage (casper)" justo después de "var page = require ('webpage'). Create ();" agregue el siguiente código:
Luego, dentro de "page.onResourceReceived = function onResourceReceived (resource) {" en la primera línea, agregue:
Haga lo mismo para "page.onResourceRequested = function onResourceRequested (requestData, request) {"
Finalmente, en "page.onLoadFinished = function onLoadFinished (estado) {" en la primera línea, agregue:
Y eso es todo, espero que esto ayude a alguien en problemas como yo. Esta solución es para casperjs pero funciona directamente para Spooky.
Buena suerte !
fuente
Esta es mi solución, funcionó para mí.
fuente