(As a quick aside: I think there is a cut-and-paste error in line 14. I believe you want #{url}
in place of #{page.reason_url}
.)
I see two issues here, or one issue manifest in a couple of ways.
The page.open
method is asynchronous -- that's why it accepts a callback function (your (status)->...
stuff).
That's causing two types of problem for your code:
Your phantom.exit()
call on line 28 is outside of the scope of the for
loop (that starts on line 9) and of the callback method (that starts on line 12).
Because the open
call is asynchronous, when urls
is ['http://google.com']
, the for
loop will call page.open('http://google.com/')
and then jump to phantom.exit()
BEFORE the page has finished loading or the callback is invoked.
You need to defer your phantom.exit()
call until the page.render(output)
method is complete. Moving phantom.exit()
right after -- and at the same of indentation as -- page.render(output)
will make your program work for a single URL.
Even with phantom.exit
inside the callback, you'll still have a problem when more than one URL is passed to your program. Again, because page.open
is asynchronous, you're effectively calling page.open
several times in quick succession (and then exiting before all of those pages have loaded).
Moreover, like a regular, single, web-browser tab, Phantom's page
object can't really open multiple pages at a time.
To fix your program need to ensure that (a) one URL has been loaded and rendered
before moving on to the next one, and (b) that you don't call phantom.exit()
until all of the URLs have been rendered.
There are a few ways to go about this (google for "nodejs asynchronous for loop" or something like that), but depending upon your needs, it may be easier to just render one page per invocation of the program.
Here's a version of your program, updated for PhantomJS 2 and set up to render exactly one URL:
system = require('system')
page = require('webpage').create()
page.viewportSize =
width: 1024
height: 760
url = system.args[2]
output = "screenshot-#{Date.now()}.png"
page.open url, (status) ->
if status isnt 'success'
console.error "Error opening url \"#{url}\": #{page.reason}"
phantom.exit(1)
else
console.log "Page opened..."
window.setTimeout (->
page.clipRect =
top: 0
left: 0
width: 1024
height: 760
page.render(output)
console.log "Page rendered..."
phantom.exit()
), 200
Since Phantom no longer parses CoffeeScript directly, to run this you'll need to first "compile" to JavaScript, like so:
coffee -c foo.coffee
phantomjs foo.js "http://www.google.com/"
This seems to work properly for me.