Nightmarejs .click() для каждого элемента с задержкой между

Я пытаюсь сделать простой сценарий с помощью Nightmarejs. Это должно работать следующим образом:

  1. Перейти к какому-либо профилю пользователя
  2. Нажмите на кнопку, чтобы открыть список подписчиков этого пользователя
  3. Нажмите все кнопки follow с задержкой между каждым нажатием.
  4. Нажмите загрузить еще.
  5. Повторите шаги 3 и 4 несколько раз.

Что у меня есть до сих пор, это работает без ошибок, но он нажимает только на первую кнопку подписки, и это конец:

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

nightmare
.goto('http://example.com/')
.click('.buttonOpenModal')
.wait(4000)
.click('.buttonFollow')
  .end()
  .then(function (result) {
    console.log(result)
  })
  .catch(function (error) {
    console.error('Search failed:', error);
  });

Я пытался циклически нажимать на кнопки подписки, как это, но это дает мне ошибку $ не определено

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

nightmare
.goto('http://example.com/')
.click('.buttonOpenModal')
.wait(4000)
.evaluate(function(){
    $('.buttonFollow').each(function() {
      $(this).click();
    });
  })
  .end()
  .then(function (result) {
    console.log(result)
  })
  .catch(function (error) {
    console.error('Search failed:', error);
  });

Я считаю, что для тех, кто имеет опыт работы с Nightmarejs, это будет простой задачей, но я только начал с этого и бьюсь с ним уже 2 дня.

Буду очень признателен за любую помощь.


person Plavookac    schedule 09.08.2016    source источник


Ответы (2)


Вы получаете $ is not defined, потому что этот синтаксис является частью jQuery, когда вы пишете сценарий NightmareJS, он использует чистый javascript.

Вы можете загрузить библиотеку jquery (перед оценкой) благодаря функции .inject("js", "https://code.jquery.com/jquery-3.1.0.min.js")

Нам нужен синхронный сон, иначе NightmareJS может завершить функцию ̀evaluate до ее завершения. (Я нашел код для sleep в этой теме: https://stackoverflow.com/a/17532524/6479780) Если вы хотите попробовать асинхронный сон, вы должны использовать setTimeout(callback, millis) Вот что я бы сделал, используя чистый javascript:

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

nightmare
.goto('http://example.com/')
.click('.buttonOpenModal')
.wait(4000)
.evaluate(function(){
    function sleep(ms) {
     var start = new Date().getTime(), expire = start + ms;
     while (new Date().getTime() < expire) { }
     return;
    }

    var list = document.querySelectorAll('.buttonFollow');
    list.forEach(function(elt){
       elt.click();
       //We need synchronous sleep here
       sleep(2000); //Wait 2 seconds
    });
  })
.end()
.then(function (result) {
    console.log(result)
})
.catch(function (error) {
    console.error('Search failed:', error);
});
person Omar    schedule 09.08.2016
comment
Я понимаю. Это работает, но щелкает все сразу, не могли бы вы редактировать с задержкой между каждым? И если я правильно понял, в принципе вы можете добавить любую чистую функцию javascript внутри .evaluate? Спасибо! - person Plavookac; 10.08.2016
comment
Код в оценке будет выполнен в окне, открытом кошмаром. Таким образом, вы открываете новую вкладку в своем браузере, вводите адрес веб-сайта и вставляете содержимое функции evaluate в консоль. Вот почему чистый javascript работает - person Omar; 10.08.2016
comment
Электронный браузер зависает, когда он спит вот так - person RetroCode; 01.09.2016

Попробуйте эту версию:

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

nightmare
  .goto('http://example.com/')
  .click('.buttonOpenModal')
  .wait('div.Buttons')
  .evaluate(function () {
    var interval = setInterval(function () {
      var btn = document.querySelectorAll('div.Buttons');
      if (undefined == btn || 0 == btn.length) {
        clearInterval(interval);
      }
      else {
        btn[0].click();
      }
    }, 5000);
  })
  .end()
  .then(function (result) {
    console.log(result)
  })
  .catch(function (error) {
    console.error('Search failed:', error);
  });
person GeorgeZ    schedule 24.11.2016