以下代码要求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, true, window, 1, 0, 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()
})
})
})
})
用setTimeout()
替换Meteor.setTimeout()
会导致另一个错误:
phantom stdout: ReferenceError: Can't find variable: Meteor
答案 0 :(得分:9)
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)
})
您可以通过直接访问定义here的内容来缩短代码,而不是使用第二个page.evaluate()
调用:
setTimeout(function() {
page.get("content", function(content) {
doSomething()
})
}, 5000)
答案 1 :(得分:0)
这不是一个很好的解决方案,但如果您只想处理按钮点击和表单提交的页面更改,则可以使用。 只需在page.open()之外声明函数变量,然后在里面为它们分配页面评估函数。在页面重新加载按钮点击后的更改后,将调用onLoadFinished,然后您可以再次对其进行评估。
xcodebuld
它不漂亮但它有效。