Capturing web page screenshots from Ruby

30 Apr 2013

A few days ago I’ve discovered that stopped to deliver web page screenshots for my DNS checking tool.

I don’t know when it happened, at some point back in time I’ve noticed that they are serving a placeholder image instead of screenshots. After a quick investigation I’ve found that they have a quota for the free usage tier now.

I’m missing the thumbnails, they make the reports to look more attractive with a better look and feel. I’ve checked for alternatives and I’ve found nothing to satisfy my needs. Considering today’s ridiculous prices of a VPS and bandwidth I decided that I would implement a simple service which will generate web page screenshots and store them on Amazon S3.

The first thing which came into my mind was PhantomJS, I could generate screenshots using PhantomJS. After analyzing Node.js gluing modules for PhantomJS I decided that I shouldn’t add another piece to manage in my stack. I settled to a Ruby solution, thanks to Capybara and Poltergeist it was trivial to implement:

require "capybara/dsl"
require "capybara/poltergeist"

class Screenshot
  include Capybara::DSL

  # Captures a screenshot of +url+ saving it to +path+.
  def capture(url, path)
    # Browser settings
    page.driver.resize(1024, 768)
    page.driver.headers = {
      "User-Agent" => "Webshot 1.0",

    # Open page
    visit url

    if page.driver.status_code == 200
      # Save screenshot
      page.driver.save_screenshot(path, :full => true)

      # Resize image
      # ...
      # Handle error

# By default Capybara will try to boot a rack application
# automatically. You might want to switch off Capybara's
# rack server if you are running against a remote application
Capybara.run_server = false
Capybara.register_driver :poltergeist do |app|, {
    # Raise JavaScript errors to Ruby
    js_errors: false,
    # Additional command line options for PhantomJS
    phantomjs_options: ['--ignore-ssl-errors=yes'],
Capybara.current_driver = :poltergeist

screenshot =
screenshot.capture "", "output.png"

After adding resizing capabilities with mini_magick, I’ve packed the example as a Ruby gem (webshot):


$ gem install webshot


# Setup Capybara

# Take a screenshot of Google's home page
# and save it to a image file using png format
webshot =
webshot.capture "", "google.png"