Подтвердить что ты не робот

Может ли phantomjs работать с node.js?

Я хотел бы использовать phantomjs в моем node.js script. есть библиотека phantomjs-node, но, к сожалению, автор использовал этот странный код кофе script, чтобы объяснить, что он делает:

phantom = require 'phantom'

phantom.create (ph) ->
  ph.createPage (page) ->
    page.open "http://www.google.com", (status) ->
      console.log "opened google? ", status
      page.evaluate (-> document.title), (result) ->
        console.log 'Page title is ' + result
        ph.exit()

теперь, если бы я использовал phantomjs непосредственно с javascript, он выглядел бы как this:

var page = require('webpage').create();
page.open(url, function (status) {
    var title = page.evaluate(function () {
        return document.title;
    });
    console.log('Page title is ' + title);
});

поэтому в основном я пытаюсь записать эквивалент первого фрагмента кода выше в обычном javascript (читая кофе script документацию.. это это то, что я сделал:

// file name: phantomTest.js

var phantom = require('phantom');

phantom.create(function(ph) {
    ph.createPage(function(page) {
        page.open('http://www.google.com', function(status) {
            console.log('opened google?', status);
            var title = page.evaluate(function() {
                return document.title;
            });
            console.log('page title is ' + title);              
        });
    });
    ph.exit();
});

К сожалению, он не работает! Если я запустил

node phantomTest.js

на оболочке ничего не происходит.. ничего не возвращается и процесс не останавливается.. любые идеи?

обновление:

Я просто прочитал это в phantomjs faq:

Q: Почему PhantomJS не написан как модуль node.js?

A: Короткий ответ: "Никто не может служить двум мастерам".

Более длинное объяснение выглядит следующим образом.

В настоящее время технически очень сложно это сделать.

Каждый модуль node.js по существу является "подчиненным" в ядре node.js, т.е. "хозяин". В своем текущем состоянии PhantomJS (и включенный в него WebKit) должен иметь полный контроль (в синхронном режиме) все: цикл событий, сетевой стек и выполнение JavaScript.

Если намерение заключается в использовании PhantomJS прямо из scriptработающий в пределах node.js, такое "свободное связывание" может быть достигнуто посредством запуск процесса PhantomJS и взаимодействие с ним.

mmm.. может ли это иметь к этому какое-то отношение? но тогда вся эта библиотека не имеет смысла!

обновление 2:

Я нашел этот код в web, который делает то же самое:

var phantom = require('phantom');
phantom.create(function(ph) {
  return ph.createPage(function(page) {
    return page.open("http://www.google.com", function(status) {
      console.log("opened google? ", status);
      return page.evaluate((function() {
        return document.title;
      }), function(result) {
        console.log('Page title is ' + result);
        return ph.exit();
      });
    });
  });
});

к сожалению, что не работает либо.. тот же результат!

4b9b3361

Ответ 1

phantomjs- node не является официальным поддерживаемым пакетом npm для phantomjs. Вместо этого он реализует "тошнотворный умный мост" между node и phantom, создавая веб-сервер, который использует веб-порты для использования в качестве канала IPC между node и phantom. Я не делаю это:

Итак, мы общаемся с PhantomJS, создавая экземпляр ExpressJS, открывая phantom в подпроцессе и указывая его на специальную веб-страницу, которая превращает сообщения socket.io в вызовы alert(). Эти вызовы alert() подхватываются phantom и там вы идете!

Так что я не удивлюсь, если phantomjs- node работает, не работает, терпит неудачу или не срабатывает эффектно. Я также не ожидал, что кто-либо, кроме автора фантомов - node, сможет устранить ошибки phantomjs- node.

Ответ на ваш первоначальный вопрос - это ответ из фантомов faq: № phantom и node имеют непримиримые различия. Оба ожидают полного контроля над фундаментальными низкоуровневыми функциями, такими как цикл событий, сетевой стек и выполнение JS, поэтому они не могут взаимодействовать в рамках одного и того же процесса.

Ответ 2

Вы также можете попробовать phridge. Ваш пример был бы написан следующим образом:

var phantom;

// spawn a new PhantomJS process
phridge.spawn()
    .then(function (ph) {
        phantom = ph;
        return phantom.openPage("http://www.google.com");
    })
    .then(function (page) {
        return page.run(function () {
            // this function runs inside PhantomJS with this bound to a webpage instance
            return this.title;
        });
    })
    .then(function (title) {
        console.log('Page title is ' + title);
        // terminates the process cleanly
        phantom.dispose();
    });

Ответ 3

Теперь я являюсь новым сопровождающим для пакета phantom-node. Он больше не использует coffeescript. Вы можете сделать что-то вроде

var phantom = require('phantom');

phantom.create().then(function(ph) {
  ph.createPage().then(function(page) {
    page.open('https://stackoverflow.com/').then(function(status) {
      console.log(status);
      page.property('content').then(function(content) {
        console.log(content);
        page.close();
        ph.exit();
      });
    });
  });
});

Новая версия намного быстрее и эластична. Он также больше не использует веб-сайты.

Ответ 4

измените код на это, и он будет работать:

 var phantom = require('phantom');
 phantom.create(function(ph) {
   ph.createPage(function(page) {
     page.open("http://www.google.com", function(status) {
       console.log("opened google? ", status);
       page.evaluate((function() {
         return document.title;
       }), function(result) {
         console.log('Page title is ' + result);
         ph.exit();
       });
     });
   });
 });

Ответ 5

Вы могли бы просто расколоть PhantomJS так же, как и я, потому что это было слишком больно, когда эти обертки не работали хорошо, и пошли с Zombie.js, который также очень популярен.

Ответ 6

Кажется, это работает.

var phantom = require('phantom');

phantom.create().then(function(ph) {
  ph.createPage().then(function(page) {
    page.open('https://stackoverflow.com/').then(function(status) {
      console.log(status);
      page.property('content').then(function(content) {
        console.log(content);
        page.close();
        ph.exit();
      });
    });
  });
});

Но я пытаюсь создать html-страницу с каким-то внешним файлом script. Он не может вставить файл script. Я пробовал как следует. Обратный вызов не возвращается из строки page.injectJs('./jQuery.min.js',function() {

var phantom = require('phantom');

    phantom.create().then(function(ph) {
      ph.createPage().then(function(page) {
        page.injectJs('./jQuery.min.js', function() {
          page.property('content').then(function(content) {
            console.log(content);
            page.close();
            ph.exit();
          });
        });
      });
    });

Ответ 7

Я столкнулся с теми же проблемами, что и вы, и, по-видимому, существует известная проблема с phantomjs-node и более новыми версиями nodejs. Похоже, что он прекратил работать где-то около node 0.9.3, согласно комментариям в этом выпуске. Итак, до тех пор, пока это не будет разрешено, вам придется либо отказаться от nodejs, либо попробовать другой модуль, например node-phantom, или просто использовать exec/spawn.