Capturing web page screenshots from Ruby

30 Apr 2013

A few days ago I’ve discovered that Thumbshots.org 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"classScreenshotincludeCapybara::DSL# Captures a screenshot of +url+ saving it to +path+.defcapture(url,path)# Browser settingspage.driver.resize(1024,768)page.driver.headers={"User-Agent"=>"Webshot 1.0",}# Open pagevisiturlifpage.driver.status_code==200# Save screenshotpage.driver.save_screenshot(path,:full=>true)# Resize image# ...else# Handle errorendendend# 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 applicationCapybara.run_server=falseCapybara.register_driver:poltergeistdo|app|Capybara::Poltergeist::Driver.new(app,{# Raise JavaScript errors to Rubyjs_errors: false,# Additional command line options for PhantomJSphantomjs_options: ['--ignore-ssl-errors=yes'],})endCapybara.current_driver=:poltergeistscreenshot=Screenshot.newscreenshot.capture"http://www.google.com/","output.png"

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

Installation

$ gem install webshot

Usage

# Setup CapybaraWebshot.capybara_setup!# Take a screenshot of Google's home page# and save it to a image file using png formatwebshot=Webshot::Screenshot.newwebshot.capture"http://www.google.com/","google.png"