javascript iframe casperjs

javascript - Agrupe enlaces anidados por iframe de primer nivel usando casperjs



(1)

Si lo recibo correctamente, quiere seleccionar qué iframe obtiene de los enlaces y solo de ese iframe. Si ese es el caso, entonces puede usar simplemente switchToChildFrame para cambiar al iframe deseado y luego simplemente obtener los enlaces llamando a get_links(obj) .

Mi ejemplo tiene 3 páginas. Un index.html que carga iframe1.html dentro de un iframe e iframe1.html tiene otro iframe dentro que carga iframe2.html . Cada archivo tiene 3 enlaces dentro:

index.html

<a href="link1/from/index">Link 1 from index</a> <a href="link2/from/index">Link 2 from index</a> <a href="link3/from/index">Link 3 from index</a> <iframe src="iframe1.html"></iframe>

iframe1.html

<a href="link1/from/iframe1">Link 1 from iframe 1</a> <a href="link2/from/iframe1">Link 2 from iframe 1</a> <a href="link3/from/iframe1">Link 3 from iframe 1</a> <iframe src="iframe2.html"></iframe>

iframe2.html

<a href="link1/from/iframe2">Link 1 from iframe 2</a> <a href="link2/from/iframe2">Link 2 from iframe 2</a> <a href="link3/from/iframe2">Link 3 from iframe 2</a>

y la función refactored getLinksFromIframes sería así:

function getLinksFromIframes(callback) { this.echo("Here we come: " + this.getCurrentUrl() + "/n"); function to_frame(obj) { obj.echo("We are here: " + obj.getCurrentUrl()); var l = unique(get_links(obj)); var i; for (i = 0; i < l.length; i++) { console.log(l[i]); links.push(l[i]) } links = unique(links); console.log(""); } function to_evaluate(obj) { return obj.evaluate(function () { var iframes = []; [].forEach.call(document.querySelectorAll("iframe"), function (iframe, i) { iframes.push(i); }); return iframes; }) } // Leave both switchToChildFrame as comments to get the "index.html" links this.page.switchToChildFrame(0); // Uncomment to get the links of "iframe1.html" //this.page.switchToChildFrame(0); // Uncomment to get the links of "iframe2.html" to_frame(this); this.then(function () { callback.call(this); }); }

RESULTADOS

Si comenta tanto en switchToChildFrame , obtendrá los enlaces de index.html :

casperjs caspers-read-iframes.js Here we come: http://pjs.lytrax.net/node/1/ We are here: http://pjs.lytrax.net/node/1/ http://pjs.lytrax.net/node/1/link1/from/index http://pjs.lytrax.net/node/1/link2/from/index http://pjs.lytrax.net/node/1/link3/from/index Done! http://pjs.lytrax.net/node/1/link1/from/index http://pjs.lytrax.net/node/1/link2/from/index http://pjs.lytrax.net/node/1/link3/from/index

Si descomenta el primer switchToChildFrame , obtendrá los enlaces del primer nivel iframe1.html :

casperjs caspers-read-iframes.js Here we come: http://pjs.lytrax.net/node/1/ We are here: http://pjs.lytrax.net/node/1/iframe1.html http://pjs.lytrax.net/node/1/link1/from/iframe1 http://pjs.lytrax.net/node/1/link2/from/iframe1 http://pjs.lytrax.net/node/1/link3/from/iframe1 Done! http://pjs.lytrax.net/node/1/link1/from/iframe1 http://pjs.lytrax.net/node/1/link2/from/iframe1 http://pjs.lytrax.net/node/1/link3/from/iframe1

Y si descomenta el primer y el segundo switchToChildFrame , obtendrá los enlaces del segundo nivel iframe2.html :

casperjs caspers-read-iframes.js Here we come: http://pjs.lytrax.net/node/1/ We are here: http://pjs.lytrax.net/node/1/iframe2.html http://pjs.lytrax.net/node/1/link1/from/iframe2 http://pjs.lytrax.net/node/1/link2/from/iframe2 http://pjs.lytrax.net/node/1/link3/from/iframe2 Done! http://pjs.lytrax.net/node/1/link1/from/iframe2 http://pjs.lytrax.net/node/1/link2/from/iframe2 http://pjs.lytrax.net/node/1/link3/from/iframe2

Tengo el siguiente código:

var casper = require("casper").create({ // verbose: true, // logLevel: "debug", webSecurityEnabled : false }); var links = []; function get_links(obj) { return obj.evaluate(function () { var i, l = document.querySelectorAll("a"), l2 = []; for (i = 0; i < l.length; i++) { l2[i] = l[i].href; } return l2 }); } function unique(arr) { var obj = {}; for (var i = 0; i < arr.length; i++) { if (/http(.*)?/.test(arr[i])) { var str = arr[i]; obj[str] = true; } } return Object.keys(obj); } function getLinksFromIframes(callback) { this.echo("Here we come: " + this.getCurrentUrl() + "/n"); function to_frame(obj) { var iframes = to_evaluate(obj); iframes.forEach(function (index) { this.withFrame(index, function () { this.echo("We are here: " + this.getCurrentUrl()); var l = unique(get_links(this)); var i; for (i = 0; i < l.length; i++) { console.log(l[i]); links.push(l[i]) } links = unique(links); console.log(""); to_frame(this) }); }, obj); } function to_evaluate(obj) { return obj.evaluate(function () { var iframes = []; [].forEach.call(document.querySelectorAll("iframe"), function (iframe, i) { iframes.push(i); }); return iframes; }) } to_frame(this); this.then(function () { callback.call(this); }); } casper.start("http://domu-test-2/node/1", function () { getLinksFromIframes.call(this, function () { console.log("Done!/n"); var i; for (i = 0; i < links.length; i++) { console.log(links[i]); } }); }).then(function () {}).run();

Y ahora la pregunta es:

si quiero obtener enlaces mediante el iframe de primer nivel, ¿cómo debería refactorizar la función getLinksFromIframes() ? Actualmente comparten links variable ''globales''. Creo que definitivamente los links serán una lista de listas de enlaces e inicializarán una nueva lista dentro de la función withFrame , y luego pasarán esta nueva referencia a iframes secundarios. Entonces, ¿cómo debería pasarlo y ''retroceder'' en todos los enlaces en iframes anidados?