2014-09-15 3 views
0

Я хотел бы немного поиграть с PhantomJS и, в частности, с помощью скрипта , который поставляется вместе с его примерами. Цель моего теста - проверить, доступны ли английская и французская версии сайта lipsum.com. Вот мой сценарий:Несколько waitFor звонков в скрипте phantomjs

var page = require('webpage').create(), 
    server = 'http://www.lipsum.com', 
    languages = ['en', 'fr']; 

page.open(server, 'get', '', function (status) { 
    if (status !== 'success') { 
     console.log('Unable to reach the URL!'); 
    } else { 
     check(languages.shift()); 
    } 
}); 

function check(currentLanguage) { 

    console.log('Checking '+currentLanguage); 

    waitFor(function() { 
     var classes = page.evaluate(function() { 
      // Checks if the current language is selected 
      return document.getElementsByClassName('zz')[0].className; 
     }); 
     console.log("Classes for the selected element : " + classes); 
     return classes.indexOf(currentLanguage) === 0; 
    }, function() { 
     console.log(currentLanguage+' has been looked up.'); 
     currentLanguage = languages.shift(); 
     page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() { 
      page.evaluate(function (language) { 
       // We click on the link related to the next language of the stack 
       $('.'+language).trigger('click'); 
      }, currentLanguage); 
     }); 
     check(currentLanguage); 
    }); 
} 

Что бы я хотел, это то, что отображаются английские, затем французские версии страницы. Вместо этого я получаю следующий журнал:

Checking en 
Classes for the selected element : en zz 
'waitFor()' finished in 500ms. 
en has been looked up. 
Checking fr 
Classes for the selected element : en zz 
Classes for the selected element : en zz 
Classes for the selected element : en zz 
Classes for the selected element : en zz 
Classes for the selected element : en zz 
Classes for the selected element : en zz 
Classes for the selected element : en zz 
Classes for the selected element : en zz 
Classes for the selected element : en zz 
Classes for the selected element : en zz 
Classes for the selected element : en zz 
'waitFor()' timeout 

Похоже щелчку на ссылке не срабатывает, но я не могу понять, почему.

ответ

0

Проблема в том, что $.click не работает. Вы должны использовать решение от this question.

Другое дело, что вы разделяете поток управления. page.includeJs и check являются асинхронными функциями. Они должны быть вложенными и не должны идти один за другим, потому что вы только приглашаете хаос, если вы это делаете. Поскольку вам больше не нужен jQuery, это только советы для будущего.

Другое, что вы должны иметь в виду, это тайм-аут. Страница относительно медленная, поэтому тайм-аут в 3 секунды немного медленный. Вы должны либо увеличить таймаут waitFor примерно на 10 секунд, либо даже лучше зарегистрировать обработчик событий для загрузки следующей страницы. В следующем коде я сделал оба. Я также добавил правильные критерии остановки.

waitFor(function() { 
    var classes = page.evaluate(function() { 
     // Checks if the current language is selected 
     return document.getElementsByClassName('zz')[0].className; 
    }); 
    console.log("Classes for the selected element : " + classes); 
    return classes.indexOf(currentLanguage) === 0; 
}, function() { 
    console.log(currentLanguage+' has been looked up.'); 
    if (languages.length === 0) { 
     console.log("Done"); 
     phantom.exit(); 
    } 
    currentLanguage = languages.shift(); 
    //page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() { 
     page.onLoadFinished = function(){ 
      check(currentLanguage); 
     }; 
     page.evaluate(function (language) { 
      // We click on the link related to the next language of the stack 
      var ev = document.createEvent("MouseEvent"); 
      ev.initMouseEvent(
       "click", true, true, window, null, 
       0, 0, 0, 0, false, false, false, false, 0, null 
      ); 
      document.querySelector('.'+language).dispatchEvent(ev); 
     }, currentLanguage); 
    //}); 
}, 10000); 
+0

Большое спасибо! Я не сомневался в том, что был какой-то асинхронный вопрос, вы заставили меня взглянуть в нужное место. Я также увеличил тайм-аут, как это было предложено. В вашем коде есть только небольшая ошибка/опечатка: 'check (currentLanguage)' должен находиться в обратном вызове onLoadFinished. –

Смежные вопросы