Navegar/raspar enlaces hashbang con javascript(phantomjs)
web-scraping (1)
El problema aquí es que el contenido de la página se carga de forma asíncrona, pero está esperando que esté disponible tan pronto como se cargue la página.
Para raspar una página que carga contenido de forma asíncrona, debe esperar a raspar hasta que se haya cargado el contenido que le interesa. Dependiendo de la página, puede haber diferentes formas de verificar, pero lo más fácil es solo verificar a intervalos regulares algo que esperas ver, hasta que lo encuentres.
El truco aquí es averiguar qué buscar: necesitas algo que no estará presente en la página hasta que hayas cargado tu contenido deseado. En este caso, la opción más fácil que encontré para las páginas de nivel superior es ingresar manualmente las etiquetas H1 que espera ver en cada página, tecleándolas en el hash:
var titleMap = {
''#!contactUs'': ''Contact Us'',
''#!aboutUs'': ''About Us''
// etc for the other pages
};
Luego, en su bloque de éxito, puede establecer un tiempo de espera recurrente para buscar el título que desea en una etiqueta h1
. Cuando aparece, sabes que puedes renderizar la página:
if (phantom.loadStatus === ''success'') {
// set a recurring timeout for 300 milliseconds
var timeoutId = window.setInterval(function () {
// check for title element you expect to see
var h1s = document.querySelectorAll(''h1'');
if (h1s) {
// h1s is a node list, not an array, hence the
// weird syntax here
Array.prototype.forEach.call(h1s, function(h1) {
if (h1.textContent.trim() === titleMap[hash]) {
// we found it!
console.log(''Found H1: '' + h1.textContent.trim());
phantom.render(''result.png'');
console.log("Rendered image.");
// stop the cycle
window.clearInterval(timeoutId);
phantom.exit();
}
});
console.log(''Found H1 tags, but not '' + titleMap[hash]);
}
console.log(''No H1 tags found.'');
}, 300);
}
El código anterior funciona para mí. Pero no funcionará si necesita raspar los resultados de la búsqueda; necesitará encontrar un elemento de identificación o un fragmento de texto que pueda buscar sin tener que saber el título con anticipación.
Editar : Además, parece que la versión más nueva de PhantomJS ahora activa un evento onResourceReceived
cuando obtiene nuevos datos. No he investigado esto, pero es posible que pueda vincular a un oyente a este evento para lograr el mismo efecto.
Intento descargar el HTML de un sitio web generado casi en su totalidad por JavaScript. Entonces, necesito simular el acceso al navegador y he estado jugando con PhantomJS . El problema es que el sitio usa URL hashbang y parece que no puedo obtener PhantomJS para procesar el hashbang, simplemente sigue llamando a la página principal.
El sitio es http://www.regulations.gov . El valor predeterminado lo lleva a #! Home. He intentado usar el siguiente código (desde aquí ) para tratar de procesar diferentes hashbangs.
if (phantom.state.length === 0) {
if (phantom.args.length === 0) {
console.log(''Usage: loadreg_1.js <some hash>'');
phantom.exit();
}
var address = ''http://www.regulations.gov/'';
console.log(address);
phantom.state = Date.now().toString();
phantom.open(address);
} else {
var hash = phantom.args[0];
document.location = hash;
console.log(document.location.hash);
var elapsed = Date.now() - new Date().setTime(phantom.state);
if (phantom.loadStatus === ''success'') {
if (!first_time) {
var first_time = true;
if (!document.addEventListener) {
console.log(''Not SUPPORTED!'');
}
phantom.render(''result.png'');
var markup = document.documentElement.innerHTML;
console.log(markup);
phantom.exit();
}
} else {
console.log(''FAIL to load the address'');
phantom.exit();
}
}
Este código produce el hashbang correcto (por ejemplo, puedo establecer el hash en ''#! Contactus'') pero no genera dinámicamente ningún HTML diferente, solo la página predeterminada. Sin embargo, tiene una salida correcta que tiene cuando llamo a document.location.hash
.
También traté de establecer la dirección inicial para el hashbang, pero luego el guión simplemente se bloquea y no hace nada. Por ejemplo, si configuro la URL en http://www.regulations.gov/#!searchResults;rpp=10;po=0
la secuencia de comandos se bloquea después de imprimir la dirección en la terminal y nunca ocurre nada.