Search code examples
rubyseleniumwebkitcapybaracapybara-webkit

Get image file using ruby & capybara


It is image tag on the page accessed by capybara via HTTPS protocol:

<img src="path">

Is it any way to get image file from the page using capybara with any kind of driver?

I can not use something like File.read('path') because image is also accessible via HTTPS only. My latest researches brought me to such kind of solution:

  1. Visit page
  2. Save page to png (webkit driver has such useful ability)
  3. Crop image

But I do believe that pretty solution exists.

Edited 1:

I've tried out padde's solution, but here is response body:

<html><head><title>Object moved</title></head> 
    <body>
        <h2>Object moved to <a href=\"/Bledy/Blad404.aspx?aspxerrorpath=/CaptchaType.ashx\">here</a>.</h2> 
    </body>
</html>

Edited 2:

> curl -I image_path

5860cf30abf5d5480
HTTP/1.1 302 Found
Cache-Control: private
Content-Length: 168
Content-Type: text/html; charset=utf-8
Location: /Bledy/Blad404.aspx?aspxerrorpath=/CaptchaType.ashx
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Sat, 03 Nov 2012 17:18:55 GMT

Solution

  • What you probably want is a HTTPS request from Ruby if i get this right. Try:

    require 'net/https'
    
    url = URI.parse('path')
    
    Net::HTTP.start(url.host, url.port, :use_ssl => true, :verify_mode => OpenSSL::SSL::VERIFY_NONE) do |http|
      res = http.get(url.request_uri)
      open("image.png", "wb") do |f|
        f.write(res.body)
      end
    end
    

    For cropping, you can either use chunky_png (pure Ruby) or rmagick (requires ImageMagick)

    Edit: If you want to follow redirects you can do

    require 'net/https'
    
    def process_image( content )
      # do your cropping here
    
      open("image.png", "wb") do |f|
        f.write(content)
      end
    end
    
    def fetch( url )
      Net::HTTP.start(url.host, url.port, :use_ssl => true, :verify_mode => OpenSSL::SSL::VERIFY_NONE) do |http|
        response = http.get(url.request_uri)
        case response.code
        when Net::HTTPRedirection
          fetch response['location']
        else
          process_image response.body
        end
      end
    end
    
    fetch URI.parse('path')