使用 jsdom 和 node.js 发布表单
Posted
技术标签:
【中文标题】使用 jsdom 和 node.js 发布表单【英文标题】:post a form using jsdom and node.js 【发布时间】:2011-09-09 22:02:08 【问题描述】:我正在使用 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')
并且必须捕获生成的页面。
有人可以帮忙吗? 谢谢
【问题讨论】:
【参考方案1】:您需要类似: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 方法
乔什
【讨论】:
【参考方案2】:哦,伙计。这就是我们进入疯狂之地的地方。
就目前而言,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 情况。
【讨论】:
哇,正是我想要的! +1以上是关于使用 jsdom 和 node.js 发布表单的主要内容,如果未能解决你的问题,请参考以下文章
Node.js https pem 错误:routines:PEM_read_bio:no start line