Acceder al interior de un iframe (distinto dominios) con phantomjs
Phantomjs es un browser funcional (basado en WebKit) bajo línea de comandos, contiene una API y es programable a través de Javascript, permitiendo manejar (de forma automatizada) Javascript, DOM handling, CSS selector, JSON, Canvas, and SVG realmente en un navegador. Como no requiere de una interfaz X, es ideal para automatiza tareas como pruebas unitarias, captura de pantalla, extracción de datos, etc.
Instalacción
La forma más sencilla es utilizar directamente los binarios precompilados para cada una de las arquitectura disponible (Windows, Linux y OSX) o compilar.
Para Linux, podemos descargar el paquete desde el sitio oficial y descomprimir
wget http://phantomjs.googlecode.com/files/phantomjs-1.8.1-linux-x86_64.tar.bz2 bzip -d phantomjs-1.8.1-linux-x86_64.tar.bz2 tar xvf phantomjs-1.8.1-linux-x86_64.tar.bz2
Para tener acceso al binario desde cualquier punto del sistema, podemos modificar nuestro variable global PATH o crear un enlace al binario de phantomjs
#Suponiendo que hemos descomprimido en opt ln /opt/phantomjs/phantomjs-1.8.1-linux-x86_64/bin/phantomjs /usr/bin/ -s
Ejemplo
La carpeta examples, contiene una decente lista de script de ejemplos de diversas tareas, por ejemplo podemos correr el script que imprime el tiempo de carga de un sitio web.
phantomjs loadspeed.js http://deerme.org #Page title is deerme #Loading time 3145 msec
El código fuente habla por si solo.
var page = require('webpage').create(), system = require('system'), t, address; if (system.args.length === 1) { console.log('Usage: loadspeed.js <some URL>'); phantom.exit(1); } else { t = Date.now(); address = system.args[1]; page.open(address, function (status) { if (status !== 'success') { console.log('FAIL to load the address'); } else { t = Date.now() - t; console.log('Page title is ' + page.evaluate(function () { return document.title; })); console.log('Loading time ' + t + ' msec'); } phantom.exit(); }); }
Accediendo al interior de un Iframe
Por politica de seguridad, los script de distintos dominios no pueden intercambiar información entre el documento principal y el iframe, existen ciertas técnicas que permite “comunicar” como jsonp, pero el manejo de dom, ejecución de scripts, etc. no es posible. Sin embargo, phantomjs contiene la opción web-security donde podemos hacer caso omiso a las politicas tradicionales .
El script carga la página, verifica que exista jQuery (si no, lo carga), y comienza a acceder al primer iframe (ejemplo #aswift_2), el segundo (#google_ads_frame3) y finalmente obtenemos algún dato del último enlace.
/* Accessing an iframe (different domain) with phantomfs Example for deerme.org */ var page = require('webpage').create(), system = require('system'), t, address; if (system.args.length === 1) { console.log('Usage: phantomfs iframe.js <some URL>'); phantom.exit(); } t = Date.now(); address = system.args[1]; page.open(address, function (status) { if (status !== 'success') { console.log('FAIL to load the address'); } else { t = (Date.now()) - t; title = page.evaluate( function(){ return document.title; }); linkTitle = page.evaluate( function(){ // The site containing jQuery? if ( typeof(jQuery) == "undefined" ) { // Force Load page.injectJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'); } // first iframe #aswift_2 // second iframe #google_ads_frame3 return jQuery("#aswift_2").contents() .find("body") .find("#google_ads_frame3") .contents() .find("body") .contents() .find("a:last") .attr("title"); }); console.log('Loading time: ' + t + ' msec'); console.log('Webpage title: ' + title); console.log('Link title (iframe adsense): ' + linkTitle); } phantom.exit(); });
Procedemos a ejecutar el script (debemos indicar la opción –web-security=no)
phantomjs --web-security=no iframe.js http://deerme.org #Loading time: 4525 msec #Webpage title: deerme #Link title (iframe adsense): www.axia.cl
excelente, muchisimas gracias. solo con este codigo se pueden hacer muchas mas cosas que con otros softwares de elevado precio y que no ayudan tanto.
mi codigo quedo asi y deja toda la informacion que buscaba en un archivo de texto
/*
Accessing an iframe (different domain) with phantomfs
Example for deerme.org
*/
var page = require(‘webpage’).create(), system = require(‘system’), t, address;
if (system.args.length === 1)
{
console.log(‘Usage: phantomfs iframe.js ‘);
phantom.exit();
}
t = Date.now();
address = system.args[1];
page.open(address, function (status)
{
if (status !== ‘success’)
{
console.log(‘FAIL to load the address’);
}
else
{
t = (Date.now()) – t;
var ua = page.evaluate(function() {
return document.getElementById(‘content-main’).innerHTML;
});
var numero = ua.length;
if (numero < 500)
{
var ua = page.evaluate(function() {
return document.getElementById('content-main').innerHTML;
});
}
var fs = require('fs');
var path = '/data/dividendos.txt';
fs.write(path, ua, 'w');
console.log(ua);
}
phantom.exit();
});
Gracias Daniel por tu comentario. Efectivamente, phantomjs es un proyecto muy interesante para muchas áreas