Iniciar sesión

Ver la versión completa : Javascript Alguien sabe de javascript (casperjs)?



crossmax
03/04/2018, 11:48
Buenas.
Espero que por aquí alguien experto en javascript me pueda echar una mano con un problemilla que tengo. Uso casperjs que a su vez tira de phantomjs.
Llevo días intentando sacar de una web unos datos de unas tablas, pero para cargar las distintas tablas necesito hacer 'click' en unas pestañas, y no encuentro la manera de hacerlo.
Parece que para poder trabajar sobre los elementos seleccionados en un mismo contexto debo usar la funcion 'evaluate' y de esa manera consigo obtener una lista de las 5 pestañas, pero cuando las recorro solo la primera no es nula. Tiene pinta que el error puede ser por la naturaleza asincrona de js, pero por mas modificaciones que hago siguiendo ejemplos que veo por internet (usar forEach en lugar de for o let en lugar de var), no consigo navegar correctamente por las pestañas para hacer click en ellas.

Este es el codigo js:



var fs = require('fs');
var casper = require('casper').create({
pageSettings: {
loadImages: false,//The script is much faster when this field is set to false
loadPlugins: false,
userAgent: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36'
}
});
casper.start().thenOpen("http://pc.metalradar.com",
function() {
console.log("MetalRadar website opened");
});
casper.then(function(){
casper.wait(5000, function(){
this.capture('home.png');
var tabs = casper.evaluate(function() {
//return document.querySelectorAll('ul#tabul li');
return document.querySelectorAll('span.dashTitle');
});
console.log('Num Tabs: ' + tabs.length);

for(var i = 0; i < tabs.length; ++i) {
if(tabs[i]) {
console.log('Tab exists');
console.log(' form id: ' + tabs[i].id);
// create a mouse click event
var event = document.createEvent( 'MouseEvents' );
event.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
// send click to element
tabs[i].dispatchEvent( event );

var name = tabs[i].innerText + '.png'
console.log(" " + name);
casper.wait(2000, function(){
console.log(" Capturando...");
this.capture(name); //Make a screenshot for each tab
});
} else {
console.log("Null tab");
}
})

});

Esta es la salida que obtengo:



Num Tabs: 5
Tab exists
form id: dbTabLabel_69451648299582
Dashboard EUR.png
Null tab
Null tab
Null tab
Null tab
Capturando...


Si para el bucle utilizo forEach por el tema de asincronia:


tabs.forEach(function(tab) {
...
})


Me da el siguiente error:



TypeError: undefined is not a function (evaluating 'tabs.forEach'


Este es el fragmento de html que quiero navegar donde las pestañas estan definidas como <li id="dbTab_**********":


<!--TEMPLATES-->
<ul id="tabul">
<li id="litab" class="ntabs add"><a href="" id="addtab" class="osx">+</a></li>
<li id="litab" class="add rightAlign setting-item">
<img src="/Content/images/icons/expand-24x24.png" class="out-triggerer gray" onclick="fullScreen()">
</li>
<li id="default-report-export" class="rightAlign">
<a href="/report/defaultExport" download="">
<input type="image" src="/Content/images/icons/excel.gif" value="Excel" title="Export default report">
</a>
</li>
<li id="default-report-export" class="rightAlign">
<a href="/report/defaultExport?isPdf=true" download="">
<input type="image" src="/Content/images/export-pdf-24x24.png" value="Excel" title="Export default report">
</a>
</li>
<li id="dbTab_889113733777776" class="ntabs addedTab activeTab">
<span id="dbTabLabel_889113733777776" class="dashTitle" onclick="clickDashboard('889113733777776')">Dashboard EUR</span>
<span id="dbTabSettings_889113733777776" class="settingsContainer dashSettings" style="">
<div id="topnav" class="topnav">
<a href="javascript:void(0)" class="signin" onclick="toggleTabSettingsMenu('889113733777776',true);">
<span><img src="/Content/Images/icon_gear.png" alt="Edit"></span>
</a>
</div>
<fieldset id="dbTabSettingsMenu_889113733777776" class="dashSettings-menu">
<ul class="dashboardEditMenu">
<img src="/Content/images/close.png" onclick="toggleTabSettingsMenu('889113733777776',false);" alt="tooltip" style="position:absolute;right:2px;top:2px;border:0;">
<li class="dashboardEditMenuList">
<a href="javascript:void(0)" class="addWidget" onclick="toggleLeftUpdatePanelMenu(true);"> Añadir widgets</a>
</li>
<li class="dashboardEditMenuList">
<a href="javascript:void(0)" class="closeDash" onclick="deleteDashboard('889113733777776')"> Borrar este dashboard</a>
</li>
</ul>
</fieldset>
</span>
</li>
<li id="dbTab_894967889413237" class="ntabs addedTab">
<span id="dbTabLabel_894967889413237" class="dashTitle" onclick="clickDashboard('894967889413237')">Dashboard USD</span>
<span id="dbTabSettings_894967889413237" class="settingsContainer dashSettings" style="display:none;">
<div id="topnav" class="topnav">
<a href="javascript:void(0)" class="signin" onclick="toggleTabSettingsMenu('894967889413237',true);">
<span><img src="/Content/Images/icon_gear.png" alt="Edit"></span>
</a>
</div>
<fieldset id="dbTabSettingsMenu_894967889413237" class="dashSettings-menu">
<ul class="dashboardEditMenu">
<img src="/Content/images/close.png" onclick="toggleTabSettingsMenu('894967889413237',false);" alt="tooltip" style="position:absolute;right:2px;top:2px;border:0;">
...
</ul>
</fieldset>
</span>
</li>
</ul>



Gracias por tragaros el tocho!!!! Si es que llegáis a leer hasta aquí. Espero haya solución a mi dolencia :rolleyes:

josepzin
03/04/2018, 11:54
Nunca he usado esa librería :S

crossmax
03/04/2018, 12:08
Nunca he usado esa librería :S

Llegados al punto en el que estoy puedo usar lo que sea para que funcione :confused:
Partí de casperjs porque ví ejemplos para hacer login sencillos y me funcionó, pero podría tirar por otro lado.
El problema es que es lo primero que hago con js y no tengo ni idea. No sé si mi problema es la asincronía, el contexto del objeto o simplemente que la web tiene un AJAX infernal.

Te dejo que me ilumines si quieres [wei5]

josepzin
03/04/2018, 12:24
Poco puedo iluminar yo! hago cosas con js pero en este caso no tengo idea... ¿no puedes tirar de JQuery?

Estopero
03/04/2018, 12:59
Seguro que ya lo has pensado, pero yo lo primero que haría es ver como se rellena esa tabla, quizás esté haciendo una consulta a un servicio para rellenarse y tú puedes consultar a ese servicio directamente?

Con la consola de chrome puedes ver las llamadas que se hacen, ya sabes.

Siempre será más facil eso que hacer un scrapping como el que estás haciendo.

Saludos!

crossmax
03/04/2018, 13:27
Seguro que ya lo has pensado, pero yo lo primero que haría es ver como se rellena esa tabla, quizás esté haciendo una consulta a un servicio para rellenarse y tú puedes consultar a ese servicio directamente?

Con la consola de chrome puedes ver las llamadas que se hacen, ya sabes.

Siempre será más facil eso que hacer un scrapping como el que estás haciendo.

Saludos!

Odio saber poco de todo :mad:
La verdad que nunca he usado la consola de chrome. Le he dado ahora y he estado mirando, pero no parece cosa de dos patadas. Hay warnings, errores y de todo a punta pala.
Cuelgo una captura a ver si me puedes decir por donde mirar, pero estoy tan perdido y quemado al mismo tiempo que dejo login de acceso a cambio de ayuda (no lo digo muy alto)

josepzin
03/04/2018, 14:25
Tienes que ir a Network y allí buscas la petición AJAX asi puedes ver los datos enviados y recibidos, a ver si eso está bien.

-----Actualizado-----

Lo que suelo hacer yo es una vez cargada la web, en esa pestaña Network, borrar toda la lista y entonces hacer la peticion AJAX, asi no tienes que buscarla.

^MiSaTo^
03/04/2018, 14:26
Qué es lo que quieres hacer exactamente? Sacar datos de una tabla de una web? No tienes acceso a la API que use? La idea de mirar en la consola de chrome o firefox, en Network, es muy buena idea porque ahí puedes ver qué API está llamando. Eso será siemrpe mejor que parsear HTML desde javascript.
Y has elegido javascript porque lo quieres poner tú en una web? Porque si no puedes usar cualquier otro lenguaje, a mi para hacer este tipo de "scripts" me gusta usar python.

josepzin
03/04/2018, 14:28
La consola del explorador es muy útil para arreglar estos problemas.

crossmax
03/04/2018, 15:07
Que maquinas sois. Por lo que veo parece que la petición genera un json de apirest? o eso creo. No tengo mucha idea de eso.
Hay 2 temas ahora. Que si en lugar de parsear tiro de API, tendré que pasarle un token valido me imagino para que entienda que estoy logueado, y no se como hacerlo. Lo segundo es como puedo ir probando llamadas al api de una manera rapida para hacer las primeras pruebas. ¿Desde el navegador con una url con parametros, desde algun simulador??

Esto es lo que veo al hacer click en la pestaña:
51342

Y la respuesta que la veo en la pestaña Response de Network (Console) es un chorrazo de datos en un json


{"data":{"w":[{"r":[{"c":[{"x":1,"v":"1522759861.06","i":"QUOTE-DATETIME"},{"x":2,"v":"1.22917","i":"BID-PRICE"},{"x":3,"v":"1.2293","i":"ASK-PRICE"}],"i":"USD"},{"c":[{"x":1,"v":"1522759851.3128","i":"QUOTE-DATETIME"},{"x":2,"v":"1.237604","i":"BID-PRICE"},{"x":3,"v":"1.237834","i":"ASK-PRICE"}],"i":"USD03M"},{"c":[{"x":1,"v":"1522759860.928","i":"QUOTE-DATETIME"}......

^MiSaTo^
03/04/2018, 15:13
Hombre lo suyo es si pudieras conseguir tú ese JSON. Para hacer pruebas de llamadas no te puedo aconsejar a no ser que estés en Mac. Pero hay un mogollón de programas para hacer llamadas HTTP y ver resultados :)
Sabes cómo se consigue ese token? Entiendo que la web de la que quieres sacar los datos no es tuya no?

crossmax
03/04/2018, 15:25
La web no es mía. Quizás tengo que mezclar javascript con la llamada al api para obtener el json y sacar de ahí los datos.
Voy a probar cosas para ver de que manera puedo pasarle el token.

romeroca
03/04/2018, 18:10
Puedes instalar plugins en Firefox o Chrome para estas cosas.

Prueba "rest-easy"

FlipFlopX
03/04/2018, 19:42
Que maquinas sois. Por lo que veo parece que la petición genera un json de apirest? o eso creo. No tengo mucha idea de eso.
Hay 2 temas ahora. Que si en lugar de parsear tiro de API, tendré que pasarle un token valido me imagino para que entienda que estoy logueado, y no se como hacerlo. Lo segundo es como puedo ir probando llamadas al api de una manera rapida para hacer las primeras pruebas. ¿Desde el navegador con una url con parametros, desde algun simulador??

Esto es lo que veo al hacer click en la pestaña:
51342

Y la respuesta que la veo en la pestaña Response de Network (Console) es un chorrazo de datos en un json


{"data":{"w":[{"r":[{"c":[{"x":1,"v":"1522759861.06","i":"QUOTE-DATETIME"},{"x":2,"v":"1.22917","i":"BID-PRICE"},{"x":3,"v":"1.2293","i":"ASK-PRICE"}],"i":"USD"},{"c":[{"x":1,"v":"1522759851.3128","i":"QUOTE-DATETIME"},{"x":2,"v":"1.237604","i":"BID-PRICE"},{"x":3,"v":"1.237834","i":"ASK-PRICE"}],"i":"USD03M"},{"c":[{"x":1,"v":"1522759860.928","i":"QUOTE-DATETIME"}......

Postman te puede valer, usar Angular cómo lo ves?

hardyx
09/04/2018, 10:24
Abre la página en Chrome y pulsa F12 para abrir el depurador. Entra con el usuario en la web y luego ve en la ventana de depuración a la pestaña Network, ahí podrás ver las llamadas que ha hecho al servidor y sus parámetros.

crossmax
09/04/2018, 17:43
Me he liado a probar postman (https://www.getpostman.com/) y la verdad es que tiene una pintaza. A ver si me voy soltando y le voy pillando el truco, pero me parece mejor opcion en mi caso que simular el navegador con casprjs como estaba haciendo.
Mas o menos ya tengo el login y la peticion al api del json con las tablas, pero veo que me las esta devolviendo siempre en dolares, cuando en el navegador, segun pincho en una pestaña me las muestra en euros o dolares.

Por lo que veo en el depurador, los valores del json estan en dolares cuando pincho en la pestaña de euros, por lo que supongo que en algun sitio debe estar realizando la conversion.
¿Sabeis por donde puedo mirar para ver donde y qué convierte los valores del json para acabar mostrándolos en dolares en el navegador??

Muchas gracias!! Y gracias por mi nuevo descubrimiento de postman :awesome:

^MiSaTo^
09/04/2018, 17:57
Me he liado a probar postman (https://www.getpostman.com/) y la verdad es que tiene una pintaza. A ver si me voy soltando y le voy pillando el truco, pero me parece mejor opcion en mi caso que simular el navegador con casprjs como estaba haciendo.
Mas o menos ya tengo el login y la peticion al api del json con las tablas, pero veo que me las esta devolviendo siempre en dolares, cuando en el navegador, segun pincho en una pestaña me las muestra en euros o dolares.

Por lo que veo en el depurador, los valores del json estan en dolares cuando pincho en la pestaña de euros, por lo que supongo que en algun sitio debe estar realizando la conversion.
¿Sabeis por donde puedo mirar para ver donde y qué convierte los valores del json para acabar mostrándolos en dolares en el navegador??

Muchas gracias!! Y gracias por mi nuevo descubrimiento de postman :awesome:
Eso seguramente lo está haciendo el javascript de la página. Te va a tocar leer el código pero mira a ver si hay una petición a algo de valores de monedas cuando cargas la página o algo así.

alexweb
26/05/2018, 16:36
oye estoy realizando un curso de html online y también hay uno de javascript, si te interesa, te dejo el link, www.megacursos.com