我在让phantomJS点击网站上的登录按钮时遇到问题。
我可以在我的第二个屏幕截图中看到它正在尝试选择登录按钮,但我无法让它等待并在下一页上截取屏幕截图。
这是我的JS文件:
var page = require('webpage').create();
page.viewportSize = {width: 1920,height: 1080};
page.open('http://clubs.bluesombrero.com/default.aspx?portalid=1809', function (status) {
console.log("Status: " + status);
if (status === "success") {
var url = page.url;
console.log('URL: ' + url);
console.log("TC0001: Pass");
page.render('TC0001.png');
var a = page.evaluate(function() {
return document.querySelector('#dnn_dnnLOGIN_cmdLogin');
});
page.sendEvent('click', a.offsetLeft, a.offsetTop);
page.render('TC0002.png');
} else {
console.log("TC0001: Failed, Page did not load.");
}
phantom.exit();
});
我已经尝试了一些方法让它等待页面加载后截取屏幕截图,但我没有运气。
答案 0 :(得分:3)
page.sendEvent()
是一个同步函数,一旦完成其动作就会完成。即使在点击触发的请求被应答之前,也会执行下一个调用(page.render()
)。
setTimeout
JavaScript提供了两个等待一段时间的函数:setTimeout
和setInterval
:
page.sendEvent('click', a.offsetLeft, a.offsetTop);
setTimeout(function(){
page.render('TC0002.png');
phantom.exit();
}, 5000);
(不要忘记删除其他phantom.exit()
,因为您不想过早退出)
当然问题在于,一方面,页面在5秒后仍然可能没有准备好,或者另一方面页面加载速度非常快,只是坐在那里什么都不做。
waitFor
更好的方法是使用PhantomJS的examples文件夹中提供的waitFor()
function。您可以等待页面的特定条件,例如特定元素的存在:
page.sendEvent('click', a.offsetLeft, a.offsetTop);
waitFor(function _testFx(){
return page.evaluate(function(){
return !!document.querySelector("#someID");
});
}, function _done(){
page.render('TC0002.png');
phantom.exit();
}, 10000);
page.onLoadFinished
另一种方法是收听加载下一页时将被调用的page.onLoadFinished
事件,但是在点击之前你应该注册它:
page.onLoadFinished = function(){
page.render('TC0002.png');
phantom.exit();
};
page.sendEvent('click', a.offsetLeft, a.offsetTop);
page.onPageCreated
只要在桌面浏览器中打开新窗口/选项卡,就会在PhantomJS中触发page.onPageCreated
。它提供了对新创建页面的引用,因为不会覆盖上一页。
page.onPageCreated = function(newPage){
newPage.render('TC0002.png');
newPage.close();
phantom.exit();
};
page.sendEvent('click', a.offsetLeft, a.offsetTop);
在所有其他情况下,page
实例将被新页面覆盖。
这可能还不够,因为PhantomJS没有指定加载页面时的含义,并且页面的JavaScript可能仍会进一步请求构建页面。这个Q& A有一些很好的建议,等待一个完整的"页面加载:phantomjs not waiting for “full” page load