使用jsdom和node.js发布表单

我正在使用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')的forms,并且必须捕获结果页面。

任何人都可以帮忙吗? 谢谢

天啊。 这是我们进入疯狂的土地的地方。

就目前而言,jsdom和“浏览器”之间的主要区别是我们可以从外部访问窗口。 例如,在你的例子中,你设置$window.$ ,这基本上是说“嘿,这个当前窗口我想要一个jQuery对象的引用”。 你可以有10个窗口,并持有所有$的引用。

现在,可以说,由于表单提交/链接点击加载一个新的页面…

JSDOM将需要重新加载窗口并更新JavaScript上下文(可能会注入您在原始jsdom.env调用中提供的脚本)。 不幸的是,您从最后一个窗口所持有的参考文献将不会被覆盖。 换句话说,在页面重新加载之后调用$(...)会导致意外的行为(很可能是内存泄漏或者在前一页中select了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使用它的Ajaxtypes的请求。 在野外我还没有看到这种用途,但理论上应该是可能的。

另一种方法是直接根据http库上的节点(或者你所依赖的请求)来做你自己的post。

要么: https : //github.com/mikeal/request/blob/master/main.js#L357

http://nodejs.org/docs/v0.4.8/api/http.html#http.request方法POST

玩笑