Search code examples
node.jsnightmare

Click function not executing executing Nightmare.js


I'm trying to do some scraping with nightmare and my work is almost functional. The problem is that I'm facing an issue when I try to perform a click() after the evaluate() and run() have been called. After I run those two functions I'm trying to perform another click to move myself to another part of the website, but is not executing the click().

At this point I'm note sure whats the issue, I have few assumptions, maybe those functions are asynchronous and I'm trying to click() when the callbacks arent ready yet or one of those functions ends de current nightmare object and I dont have the scope anymore.

var Nightmare = require('nightmare');
//var nightmare = Nightmare({show:true})
var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app     = express();

var urlWeb = "someurl";
var selectCity = "#ddl_city";
var selectTheater = "#ddl_theater";
var enterBtn = "#btn_enter";
var mainSelector = "#aspnetForm";
var flagReady = true;

new Nightmare({show:true})
.goto(urlWeb)
.wait(selectCity)
.select(selectCity, '19')
.wait(8000)
.select(selectTheater, '12')
.wait(1000)
.click(enterBtn)
.wait(mainSelector)
.evaluate(function(){

        //returning HTML for cheerio
        return document.body.innerHTML; 
})
.run(function(err, nightmare){
     if (err) return console.log(err);

    // Loading HTML body on jquery cheerio
     var $ = cheerio.load(nightmare);

    //Looping on each div for seccion de Carterla para Hoy
    $('.showtimeDaily').each(function(index, element){
        //spanish title
        console.log($(this).find('h3').children().text());
        //english title
        console.log($(this).find('h4').text());
        //schedule for today
        console.log($(this).find('li').children().text() + " ");
        //img for movie
        console.log($(this).find('img').attr('src'));
            //show time data such as gender, lenght, language
        console.log($(this).find('.showtimeData').text());
        var showtimeData = $(this).find('.showtimeData').text();
        //console.log(JSON.stringify(showtimeData.replace(/\t|\n/g, "")));
    })

        console.log('Done!');


})
//*****here is wen I try to click*****
.click('a[href="../showtimes/weekly.aspx"]');

Solution

  • I was having issue with the asynchronous call backs, so what I did is that I nested calls of the nightmare object to make sure that the tasks were running one after the other one. This is the code:

    nightmare
    .goto(urlWeb)
    .wait(selectCity)
    .select(selectCity, '19')
    .wait(8000)
    .select(selectTheater, '12')
    .wait(1000)
    .click(enterBtn)
    .wait(mainSelector)
    .evaluate(function(){
    
            //returning HTML for cheerio
            return document.body.innerHTML; 
    })
    .then(function(body){
        // Loading HTML body on jquery cheerio
         var $ = cheerio.load(body);
    
        //Looping on each div for seccion de Carterla para Hoy
        $('.showtimeDaily').each(function(index, element){
            //spanish title
            console.log($(this).find('h3').children().text());
            //english title
            console.log($(this).find('h4').text());
            //schedule for today
            console.log($(this).find('li').children().text() + " ");
            //img for movie
            console.log($(this).find('img').attr('src'));
                //show time data such as gender, lenght, language
            console.log($(this).find('.showtimeData').text());
            var showtimeData = $(this).find('.showtimeData').text();
            //console.log(JSON.stringify(showtimeData.replace(/\t|\n/g, "")));
        })
       //**Here I call nightmare to run after the first call back is done*****
        nightmare
            .goto('')
            .wait('body')
            .title()
            .then(function(title){
                console.log(title);
            });
    
            console.log('Done!');
    
    
    });