Search code examples
javascriptnode.jsnightmare

How to chain a variable amount of methods on node js?


I'm using Nightmarejs to scrap a website. I want to chain multiple operations (promises?) depending on some input. Take the following code:

var Nightmare = require('nightmare');       
var nightmare = Nightmare({ show: true });

nightmare
   .goto('https://www.servipag.com/')
   .select('select#servicios.txt_formulario', '29')
   .wait(200)
   .select('select#billers', '700')
   .insert('input#identificador','60957924')
   .click('#formPagoCuentas a[href^="javascript:AgregarCuentasaPagar"]')
   .wait(10)
   .click('#formPagoCuentas a[href^="javascript:enviar"]')
   .wait('fieldset')
   .evaluate(function () {
     return document.querySelector('.txt_detalle_boleta').innerHTML;
   })
   .end()
   .then(function (result) {
     console.log(result);
   })
   .catch(function (error) {
     console.error('Search failed:', error);
   });

I want to be able to attach a variable amount of times (from 1 to 15) the following lines:

   .select('select#servicios.txt_formulario', '29')
   .wait(200)
   .select('select#billers', '700')
   .insert('input#identificador','60957924')
   .click('#formPagoCuentas a[href^="javascript:AgregarCuentasaPagar"]')
   .wait(10)

so the overall code for four times would be:

var Nightmare = require('nightmare');       
var nightmare = Nightmare({ show: true });

nightmare
   .goto('https://www.servipag.com/')
   // -- repeat this 4 times
   .select('select#servicios.txt_formulario', '29')
   .wait(200)
   .select('select#billers', '700')
   .insert('input#identificador','60957924')
   .click('#formPagoCuentas a[href^="javascript:AgregarCuentasaPagar"]')
   .wait(10)
   // ---
   .select('select#servicios.txt_formulario', '29')
   .wait(200)
   .select('select#billers', '700')
   .insert('input#identificador','60957924')
   .click('#formPagoCuentas a[href^="javascript:AgregarCuentasaPagar"]')
   .wait(10)
   // ---
   .select('select#servicios.txt_formulario', '29')
   .wait(200)
   .select('select#billers', '700')
   .insert('input#identificador','60957924')
   .click('#formPagoCuentas a[href^="javascript:AgregarCuentasaPagar"]')
   .wait(10)
   // ---
   .select('select#servicios.txt_formulario', '29')
   .wait(200)
   .select('select#billers', '700')
   .insert('input#identificador','60957924')
   .click('#formPagoCuentas a[href^="javascript:AgregarCuentasaPagar"]')
   .wait(10)
   // -- end
   .click('#formPagoCuentas a[href^="javascript:enviar"]')
   .wait('fieldset')
   .evaluate(function () {
     return document.querySelector('.txt_detalle_boleta').innerHTML;
   })
   .end()
   .then(function (result) {
     console.log(result);
   })
   .catch(function (error) {
     console.error('Search failed:', error);
   });

How can I do it?


Solution

  • I know nothing about nightmare, but it looks like everything is queued until you call end and it just returns itself for chaining. So this should work

      var operations = nightmare.goto('https://www.servipag.com/');
    
      for(var i = 0; i < 4; i++) {
         operations = operations
            .select('select#servicios.txt_formulario', '29')
            .wait(200)
            .select('select#billers', '700')
            .insert('input#identificador','60957924')
            .click('#formPagoCuentas a[href^="javascript:AgregarCuentasaPagar"]')
            .wait(10);
      }
    
      operations
         .click('#formPagoCuentas a[href^="javascript:enviar"]')
         .wait('fieldset')
         .evaluate(function () {
           return document.querySelector('.txt_detalle_boleta').innerHTML;
         })
         .end()
         .then(function (result) {
           console.log(result);
         })
         .catch(function (error) {
           console.error('Search failed:', error);
         });