2011-06-07 109 views
10

我使用jsdom,jquery和node.js來刮取網站。有沒有什麼辦法可以發表一個表單,並使用jsdom獲得生成的下一個頁面窗口。使用jsdom和node.js發佈表單

下面是代碼

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')並將所得頁面必須被捕獲的形式。

任何人都可以幫忙嗎? 謝謝

回答

21

哦男人。這是我們進入瘋狂的土地的地方。

就目前而言,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 
    }); 
}); 

情況因人而異,但這種做法應該在非Ajax的情況下工作。

+0

這傢伙着火了! – 2011-06-10 04:13:27

+0

太棒了!非常感謝!! :) – Madhusudhan 2011-06-10 17:09:34

+0

哇,正是我一直在尋找! +1 – 2012-05-02 21:38:10

0

你需要像這樣的東西: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方法

喬希