我有一个看起来有点...
var page = require('webpage').create();
page.onConsoleMessage = function(msg) {
console.log(msg);
};
page.open("http://www.any_website.com", function(status) {
if ( status == "success" ) {
page.evaluate(function() {
document.querySelector("input[name='MAIL_ADDRESS']").value = "any@mail.com";
document.querySelector("input[name='PASSWORD']").value = "the_real_password";
document.getElementsByName("LOGIN_FORM_SUBMIT")[0].click();
console.log("Login submitted!");
});
window.setTimeout(function () {
var ua = page.evaluate(function () {
return document.getElementById('ContentMain').innerHTML;
});
console.log(ua);
phantom.exit();
}, 20000);
}
});
就好。
但正如您可能看到的,我已经在单击登录按钮后 20 秒内实施了修复超时。我想摆脱它,我希望脚本在登录完成后立即关闭。我已经玩了几个月了,但我无法找到一个没有时间限制的解决方案,这将更加优雅、高效和强大。
有人可以帮助调整代码吗?
谢谢
PS:欢迎提供有关javascript + phantomjs功能的更多信息。我真的不知道我在这里做什么,我不知道第二个页面评估调用是否有意义。
PPS: 是否有延迟功能可以等到网站完全加载?
编辑 1:
感谢您的评论。我可以精确地"完全加载"说一个定义的字符串应该出现在数据中。我尝试了一种不同的方法来循环使用setInterval并在html数据中查找特定的字符串。
此新代码不起作用,因为脚本在步骤 1 之后挂起。我认为当我读出 page.content 值时,整个 phantomjs 处理都会停止,我不会提前获得 page.content,它在登录后任何时候都不会获得最新数据。
计划只是轮询html数据,只要我找到一个特定的字符串,我知道在加载网站时会出现该字符串。
当我将间隔增加到 5000 或更高时,可能是脚本工作,因为在最终数据出现后调用了 page.content?!(不确定,但这是我的解释)
知道如何在不破坏/停止站点下载/处理的情况下轮询 html 数据吗?
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
'use strict';
if (typeof start !== 'number') {
start = 0;
}
if (start + search.length > this.length) {
return false;
} else {
return this.indexOf(search, start) !== -1;
}
};
}
var page = require('webpage').create(), testindex = 0, loadInProgress = false, delayedLoad = false;
page.onConsoleMessage = function(msg) {
console.log(msg);
};
page.onLoadStarted = function() {
loadInProgress = true;
console.log("load started");
};
page.onLoadFinished = function() {
loadInProgress = false;
console.log("load finished");
};
var steps = [
function() {
//Load Login Page
page.open("http://www.any_website.com");
},
function() {
//Enter Credentials and login
page.evaluate(function() {
document.querySelector("input[name='MAIL_ADDRESS']").value = "real_name";
document.querySelector("input[name='PASSWORD']").value = "real_password";
document.getElementsByName("LOGIN_FORM_SUBMIT")[0].click();
});
},
function() {
// Output content of page to stdout after form has been submitted
page.render('out.png');
page.evaluate(function() {
console.log(document.getElementById('ContentMain').innerHTML);
});
}
];
// this is for signalizing phantomjs when all the data has finished loading
var stepstop = [ "", "Stop Text at the End of the needed Data", ""];
interval = setInterval(function() {
if (!loadInProgress && typeof steps[testindex] == "function") {
if (delayedLoad == false) {
console.log("step " + testindex);
steps[testindex]();
}
if (stepstop[testindex] != "") {
var tempHTML = page.content;
// console.log("b " + tempHTML.length);
console.log("c " + stepstop[testindex]);
// console.log("d " + tempHTML);
console.log("e " + tempHTML.includes(stepstop[testindex]));
if (tempHTML.includes(stepstop[testindex]) != false) {
console.log("step " + testindex + ": HTML stop found");
delayedLoad = false;
testindex++;
} else {
console.log("step " + testindex + ": HTML stop not found");
delayedLoad = true;
}
} else {
console.log("step " + testindex + ": no HTML stop search needed");
testindex++;
}
}
if (typeof steps[testindex] != "function") {
console.log("shutdown phantom");
phantom.exit();
}
}, 100);
好的...终于我找到了解决方案...
我完全从phantomjs切换到Selenium + Webdriver(Chrome浏览器)+ C# API。
这对我来说效果更好,它允许实现更复杂的机制来查找用户定义的"加载完成"标准。
也许只有我一个人,但是对于PhantomJS和JavaScript,我并没有设法找到解决方案。