опубликуйте форму, используя jsdom и node.js - PullRequest
10 голосов
/ 07 июня 2011

Я использую jsdom, jquery и node.js для очистки веб-сайтов. Можно ли как-нибудь опубликовать форму и получить окно следующей страницы с помощью jsdom.

Вот код

var httpAgent = require('http-agent'),
    jsdom = require('jsdom'),
    request = require('request');

request({uri:'http://www.orbitz.com'}, function(error, response, body){
  if(error && response.statusCode != 200)
    console.log('Error on request');

  jsdom.env({
    html: body,
      scripts : [
        'http://code.jquery.com/jquery-1.5.min.js'
      ]
    }, function(err, window) {
          var $ = window.jQuery;

          $('#airOneWay').attr('checked', true);
          $('#airRoundTrip').removeAttr('checked');
          $('#airOrigin').val('ATL');
          $('#airDestination').val('CHI');

          // here we need to submit the form $('#airbotForm') and get the resulting window
          //console.log($('#airbotForm').html());
   });
});

Это форма, которую необходимо отправить $('#airbotForm'), и получившаяся страница должна быть захвачена.

Кто-нибудь может помочь? Спасибо

Ответы [ 2 ]

21 голосов
/ 10 июня 2011

О человек. Вот где мы попадаем в безумную землю.

В сущности, ключевое различие между jsdom и «браузером» в том, что мы можем получить доступ к окну извне. Например, в вашем примере вы устанавливаете $ на window.$, что в основном говорит "эй, для этого текущего окна я хочу ссылку на объект jquery". Вы можете иметь 10 окон и хранить ссылки на все их $.

Теперь предположим, что вы загружаете новую страницу из-за отправки формы / клика по ссылке ...

JSDOM потребуется перезагрузить окно и обновить контекст javascript (возможно, внедрить сценарии, которые вы предоставили в исходном вызове jsdom.env). К сожалению, ссылки, которые вы держали в последнем окне, будут удалены / перезаписаны. Другими словами, вызов $(...) после перезагрузки страницы может привести к неожиданному поведению (скорее всего, утечка памяти или выбор элементов dom на предыдущей странице)

Как вы справляетесь с этим?

Поскольку вы уже используете jquery, сделайте что-то вроде ..

var form   = $('#htlbotForm');
var data   = form.serialize();
var url    = form.attr('action') || 'get';
var type   = form.attr('enctype') || 'application/x-www-form-urlencoded';
var method = form.attr('method');

request({
  url    : url,
  method : method.toUpperCase(),
  body   : data,
  headers : {
    'Content-type' : type
  }
},function(error, response, body) {
  // this assumes no error for brevity.
  var newDoc = jsdom.env(body, [/* scripts */], function(errors, window) {
    // do your post processing
  });
});

YMMV, но этот подход должен работать в ситуациях, не связанных с Ajax.

0 голосов
/ 09 июня 2011

Вам нужно что-то вроде: https://github.com/driverdan/node-XMLHttpRequest, и вам нужно настроить jsdom, чтобы использовать его для запросов типа ajax.Я не совсем видел этот тип использования в дикой природе, но это должно быть возможно теоретически.

Другой способ - это сделать свою собственную публикацию непосредственно на основе узлов в библиотеке http (или запроса, который выКажется, зависит от).

Либо: https://github.com/mikeal/request/blob/master/main.js#L357

http://nodejs.org/docs/v0.4.8/api/http.html#http.request с методом POST

Джош

...