Хобрук: Ваш путь к мастерству в программировании

Вход в систему Phantomjs, перенаправление и отображение страницы после завершения загрузки страницы

У меня есть сайт с формой входа. Если пользователь не вошел в систему и попытается получить доступ к внутренней странице, он будет перенаправлен на страницу по умолчанию. Например, если я попытаюсь получить доступ к http://siteURL.PhantomPrint.aspx, я буду перенаправлен на http://siteURL/Default.aspx?ReturnUrl=PhantomPrint.aspx., а после входа в систему произойдет автоматическое перенаправление на страницу.

После перенаправления я хочу отобразить страницу с помощью Phantomjs и сохранить ее в формате pdf. Проблема в том, что рендеринг происходит до завершения загрузки страницы, и я могу правильно отобразить страницу, только если использую тайм-ауты. В этом случае, если загрузка страницы занимает больше времени, чем обычно, полученный PDF-файл не является правильным.

Ниже вы можете найти код java-скрипта:

var page = require('webpage').create(); 
var index = 0,

page.onConsoleMessage = function (msg) {
    console.log(msg);
};

var steps = [
  function () {
      //Load Login Page
      page.open("http://siteURL.PhantomPrint.aspx", function () {
          //Enter Credentials
          page.evaluate(function () {
              console.log("filling inputs");

          var usernameInput = document.getElementById("txtUsername");
          usernameInput.value = "user";

          var passwordInput = document.getElementById("txtPassword");
          passwordInput.value = "password";

          var loginButton = document.getElementById("btnLogin");
          loginButton.click();

          console.log("login button was submitted");
      });
  });
  },

   function () {
            // page.onLoadFinished = function () {
                // Render the page to pdf
                page.render('example.png');
                phantom.exit();
                console.log("rendering finished");
           //});
        }
    ];


    interval = setInterval(function () {
        if (!loadInProgress && typeof steps[testindex] == "function") {
            console.log("step " + (testindex + 1));
            steps[testindex]();
            testindex++;
        }
        if (typeof steps[testindex] != "function") {
            console.log("test complete!");
            phantom.exit();
        }
    }, 1000);

Любые предложения о том, как я могу гарантировать, что рендеринг выполняется только после завершения загрузки перенаправленной страницы, приветствуются.

10.09.2014

Ответы:


1

Похоже, вы хотите обработать шаги навигации. Вам нужно будет использовать page.onNavigationRequested, чтобы узнать, загружается ли страница /перенаправление было выпущено. Это, вероятно, будет трудно поддерживать. Вам также придется отказаться от идеи использования ступенчатого массива с setInterval.

Другой возможностью было бы специальное ожидание некоторого селектора, присутствующего на целевой странице, с помощью waitFor, но опять же, это сделало бы использование setInterval невозможным.


CasperJS фактически построен на основе PhantomJS и использует шаги для навигации по сайту. Когда вы используете любую из функций then*, она автоматически подхватит загрузку страницы и дождется окончания загрузки страницы до выполнения обратного вызова.

var casper = require('casper').create(); 

casper.on("remote.message", function (msg) {
    console.log(msg);
});

casper.start("http://siteURL/PhantomPrint.aspx", function () {
    //Enter Credentials
    this.evaluate(function () {
        console.log("filling inputs");

        var usernameInput = document.getElementById("txtUsername");
        usernameInput.value = "user";

        var passwordInput = document.getElementById("txtPassword");
        passwordInput.value = "password";
    });
    this.click("#btnLogin");
    this.echo("login button was submitted");
});
casper.then(function () {
    this.capture('example.png');
});
casper.run();

Его можно сделать еще меньше, используя casper.fillSelectors.

10.09.2014
  • Привет, это звучит как хорошее решение, но у меня есть одна проблема. Я не могу заставить PhantomJs работать с CasperJs. Я получаю следующую ошибку Fatal: система не может найти указанный файл; вы установили фантомы?. У меня есть каталог PhantomJs, в котором есть файл phantomjs.exe. Внутри него у меня есть подпапка CasperJs, в которой есть 2 подпапки: batchbin и bin. JS, который я хочу запустить, находится внутри CasperJs\bin. Как я могу настроить запуск casperjs? Потому что я понятия не имею, и я не мог найти подходящего решения в Интернете. 12.09.2014
  • Вам нужно добавить местоположение (путь к папке) фантомов в переменную среды PATH. Если бы вы установили phantomjs и casperjs через npm, это произошло бы автоматически. 12.09.2014

  • 2

    После дополнительных исследований я нашел решение, см. код ниже.

    var loadInProgress = false;
    
    page.onLoadStarted = function () {
        loadInProgress = true;
        console.log("load started");
    };
    
    page.onLoadFinished = function () {
        loadInProgress = false;
        console.log("load finished");
    };
    
    interval = setInterval(function () {
        if (!loadInProgress && typeof steps[testindex] == "function") {
            console.log("step " + (testindex + 1));
            steps[testindex]();
            testindex++;
        }
        if (typeof steps[testindex] != "function") {
            console.log("test complete!");
            phantom.exit();
        }
    }, 100)
    

    Но я хотел бы знать, нет ли другого решения, которое не включало бы рекурсивный вызов функций.

    10.09.2014
  • Я не вижу никакой рекурсии. 10.09.2014
  • Новые материалы

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

    Обзор: Машинное обучение: классификация
    Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

    Разработка расширений Qlik Sense с qExt
    Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..