我正在使用PhantomJS使用node.js登录网站。之后我想发一个HTTP请求来获取带有数据的json。我的代码如下:
phantom.create()
.then(function (ph) {
this.ph = ph;
return ph.createPage();
})
.then(function (page) {
this.page = page;
return page.open('https://example.com');
})
.then(function (status) {
if ( status === "success" ) {
return this.page.evaluate(function() {
document.querySelector("input[name='j_username']").value = 'example@example.net';
document.querySelector("input[name='j_password']").value = 'example';
console.log('Submitting logging...');
document.querySelector("input[name='submit']").click();
});
} else {
return null;
}
})
.then(function() {
console.log("Logged in!");
this.page.property('onResourceRequested', function(requestData, networkRequest) {
//This event is fired 40 times, only one is interesting to me the one that has the text maps.json in it
if (requestData.url.indexOf('maps.json') !== -1) {
return {headers: requestData.headers, url: requestData.url};
}
});
});
.then(function (data) {
//This then block is only fired once, with the first call of the first url in previous then block and data is null
if (data) {
// This code block is never fired because this then is only called once with data=null
console.log(data);
request.get({
uri: data.url,
headers: data.headers
}, function(err, res, body){
if (!err) {
callback(null, res.headers);
} else {
console.log("Error getting data from URL: "+ err);
callback(true, null);
}
});
}
});
此后续承诺肯定有问题,因为倒数第二个块中的this.page.property('onResourceRequested'...
函数被触发40次(登录后在网站内调用每个url一个),但最后then
仅被触发一次(当请求第一个URL时)。
我想从一个具体网址(网址中包含maps.json的网址)获取数据,该网址是电话号码32.
我做错了什么?如果我的电话完成,我该如何解除最后一次?
编辑:
按照@ charlieetfl的建议,我把代码搞砸了以下内容,但仍然没有工作......:
phantom.create()
.then(function (ph) {
this.ph = ph;
return ph.createPage();
})
.then(function (page) {
this.page = page;
return page.open('https://example.com');
})
.then(function (status) {
if ( status === "success" ) {
return this.page.evaluate(function() {
document.querySelector("input[name='j_username']").value = 'example@example.net';
document.querySelector("input[name='j_password']").value = 'example';
console.log('Submitting logging...');
document.querySelector("input[name='submit']").click();
});
} else {
return null;
}
})
.then(function() {
console.log("Logged in!");
return new Promise(function(resolve, reject) {
this.page.property('onResourceRequested', function(requestData, networkRequest) {
//This event is fired 40 times, only one is interesting to me the one that has the text maps.json in it
if (requestData.url.indexOf('maps.json') !== -1) {
resolve({headers: requestData.headers, url: requestData.url});
}
});
});
});
.then(function (data) {
//This then block is only fired once, with the first call of the first url in previous then block and data is null
if (data) {
// This code block is never fired because this then is only called once with data=null
console.log(data);
request.get({
uri: data.url,
headers: data.headers
}, function(err, res, body){
if (!err) {
callback(null, res.headers);
} else {
console.log("Error getting data from URL: "+ err);
callback(true, null);
}
});
}
});
编辑:21/07/2017 10:52 UTC。
我将代码更改为新代码:
phantom.create().then(function(ph) {
ph.createPage().then(function(page) {
page.open('https://example.com/').then(function(status) {
if ( status === "success" ) {
page.evaluate(function() {
document.querySelector("input[name='j_username']").value = 'example';
document.querySelector("input[name='j_password']").value = 'example';
console.log('Submitting logging...');
document.querySelector("input[name='submit']").click();
}).then(function(){
page.property('onResourceRequested', function(requestData) {
if (requestData.url.indexOf('geomaps.json') !== -1) {
console.log(JSON.stringify(datos));
request.get({
uri: requestData.url,
headers: requestData.headers
}, function(err, res, body){
if (!err) {
console.log(res.headers);
} else {
console.log("Error getting data from website: "+ err);
}
});
}
});
});
}
});
});
});
结果相同。 console.log(JSON.stringify(datos));正在被解雇,但是request.get永远不会被解雇。
我的事情可能与在Promises中触发异步功能有关吗?
EDIT 21/07/2017 11:09 UTC
更多测试。如果我简化了page.property(' onResourceRequested'代码块,我看到then()只被调用一次,并且在每次调用收到requestData之前...
我有点困惑,我现在还不知道如何处理这个......
答案 0 :(得分:0)
我终于解决了这个问题。
page.property('onResourceRequested'
在PhantomJS进程中执行。 PhantomJS不与节点共享任何内存或变量。因此,使用javascript中的闭包来共享函数之外的任何变量是不可能的。
使用page.on('onResourceRequested'
代替解决问题!