簡體   English   中英

使用 jsdom 和 node.js 發布表單

[英]post a form using jsdom and node.js

我正在使用 jsdom、jquery 和 node.js 來抓取網站。 有什么方法可以發布表單並使用 jsdom 獲取生成的下一頁 window。

這是代碼

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')並且必須捕獲生成的頁面。

有人可以幫忙嗎? 謝謝

天啊。 這就是我們進入瘋狂之地的地方。

就目前而言,jsdom 和“瀏覽器”之間的主要區別在於我們可以從外部訪問 window。 例如,在您的示例中,您將$設置為window.$ ,這基本上是在說“嘿,對於當前的 window,我想要引用 jquery 對象”。 您可以擁有 10 個 windows,並保留對所有$的引用。

現在,假設您由於表單提交/鏈接點擊而加載了一個新頁面......

JSDOM 需要重新加載 window 並更新 javascript 上下文(可能會注入您在原始 jsdom.env 調用中提供的腳本)。 不幸的是,您從上一個 window 中持有的參考資料將被刪除/覆蓋。 換句話說,在頁面重新加載后調用$(...)會導致意外行為(很可能是 memory 泄漏或上一頁上的 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 情況。

您需要類似: 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

喬什

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM