Mad*_*han 10 jquery node.js jsdom
我正在使用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());
});
});
Run Code Online (Sandbox Code Playgroud)
这是需要提交的表单,$('#airbotForm')必须捕获生成的页面.
有人可以帮忙吗?谢谢
tmp*_*var 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
});
});
Run Code Online (Sandbox Code Playgroud)
YMMV,但这种方法应该适用于非ajax情况.