2011-06-07 22 views
10

Estoy usando jsdom, jquery y node.js para raspar sitios web. ¿Hay alguna forma de que pueda publicar un formulario y obtener la ventana de la siguiente página resultante usando jsdom?publique un formulario usando jsdom y node.js

Este es el código

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()); 
    }); 
}); 

Ésta es la forma que debe ser presentado $('#airbotForm') y la página resultante tiene que ser capturado.

¿Alguien puede ayudar? Gracias

Respuesta

21

Oh hombre. Aquí es donde entramos en la tierra loca.

Tal como está, la diferencia clave entre jsdom y "el navegador" es que podemos acceder a la ventana de forma externa. Por ejemplo, en su ejemplo establece $ en window.$, que básicamente dice "hey, para esta ventana actual quiero una referencia al objeto jquery". Puede tener 10 de Windows y contener referencias a todos sus $.

Ahora, digamos que se carga una nueva página debido a un formulario de envío/enlace de clic ...

JSDOM tendría que volver a cargar la ventana y actualizar el contexto Javascript (potencialmente la inyección de los guiones que nos ha facilitado en el original jsdom.env llamada). Desafortunadamente, la (s) referencia (s) que retuvo desde la última ventana ya no estarán/se sobrescribirán. En otras palabras, llamar al $(...) después de que la página se haya cargado generará un comportamiento inesperado (probablemente una pérdida de memoria o selección de elementos dom en la página anterior)

¿Cómo se soluciona esto?

dado que está utilizando jQuery ya, hacer algo como ..

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 
    }); 
}); 

tu caso es distinto, pero este enfoque debería funcionar en situaciones no ajax.

+0

¡Este tipo está en llamas! –

+0

simplemente increíble! ¡¡muchas gracias!! :) – Madhusudhan

+0

¡Guau, exactamente lo que estaba buscando! +1 –

0

Necesita algo como: https://github.com/driverdan/node-XMLHttpRequest y necesita configurar jsdom para usarlo para las solicitudes de tipo ajax. No he visto este tipo de uso en la naturaleza, pero debería ser posible en teoría.

La otra forma es hacer su propia publicación directamente en base a los nodos en la biblioteca http (o solicitud, de la cual usted parece depender).

O bien: https://github.com/mikeal/request/blob/master/main.js#L357

http://nodejs.org/docs/v0.4.8/api/http.html#http.request con método POST

Josh