下面的代码想要Phantom.js加载页面,点击一个按钮,等待5秒钟返回页面的
HTML代码.
问题:但是使用setTimeout()创建5秒延迟会导致
page.evaluate函数返回null到回调函数而不是HTML.
myUrl = 'http://www.google.com' var phantom = Meteor.npmRequire('phantom') phantom.create = Meteor.wrapAsync(phantom.create) phantom.create( function(ph) { ph.createPage = Meteor.wrapAsync(ph.createPage) ph.createPage(function(page) { page.open = Meteor.wrapAsync(page.open) page.open(listingUrl,function(status) { console.log('Page loaded') page.evaluate = Meteor.wrapAsync(page.evaluate) page.evaluate(function() { // Find the button var element = document.querySelector( '.search-btn' ); // create a mouse click event var event = document.createEvent( 'MouseEvents' ); event.initMouseEvent( 'click',true,window,1,0 ); // send click to element element.dispatchEvent( event ); // Give page time to process Click event setTimeout(function() { // Return HTML code return document.documentElement.outerHTML },5000) },function(html) { // html is `null` doSomething() }) }) }) })
用Meteor.setTimeout()替换setTimeout()会导致另一个错误:
phantom stdout: ReferenceError: Can't find variable: Meteor
解决方法
page.evaluate()是PhantomJS的沙盒页面上下文.它无法访问外部定义的变量.如果需要超时,则需要对page.evaluate()进行两次调用,因为您无法从异步函数(
explanation)返回任何内容:
page.evaluate(function() { ... element.dispatchEvent( event ); },function() { setTimeout(function() { page.evaluate(function() { return document.documentElement.outerHTML },function(html) { doSomething() }) },5000) })
而不是使用第二个page.evaluate()调用,您可以通过直接访问定义的内容来缩短代码here:
setTimeout(function() { page.get("content",function(content) { doSomething() }) },5000)