Search code examples
ruby-on-railsrubyseleniumnokogiriopen-uri

How can I download an image from a website using Rails?


I'm using Selenium-Webdriver, OpenUri and Nokogiri to scrape a website. I want to download a particular image from said website to my Ubuntu computer. I tried a few different methods but each of them gives a different error message.

Here's my base code, which opens the website and gets the image url (everything after this I ran in my pry console):

require 'open-url'
require 'selenium-webdriver'
require 'nokogiri'
require 'uri'

url = "https://www.google.com/"
browser = Selenium::WebDriver.for :chrome
document = open(url).read
parsed_content = Nokogiri::HTML(content)
image = "https://www.google.com" + parsed_content.css('#hplogo').attr('src').value
binding.pry

1) Here's the first thing I tried to download the image:

download = open(image)
IO.copy_stream(download, '~/image.png')

For this, I got the following error:

Errno::ENOENT: No such file or directory @ rb_sysopen - ~/image.png from (pry):44:in 'initialize'

As per this question, I tried adding a directory in the code:

FileUtils.mkdir_p(image) unless File.exist?(image)

But I got the same error.


2) Next I tried this:

open('image.png', 'wb') do |file|
  file << open(image).read
end

and this returns

#<File:image.png (closed)

but the file isn't anywhere on my computer and I can't figure out what that message means.


3) Next I tried

IO.copy_stream(open(image), 'image.png')

which simply returned this:

5482

but again, I have no idea what that means and the file isn't anywhere.


4) Finally I tried

read_image = open(image).read
File.open(image, 'image.png') do |file|
  file.puts read_image
end

which outputs

ArgumentError: invalid access mode image.png from (pry):53:in 'initialize


What am I doing wrong? Was I close with any of my approaches?


Solution

  • File open second argument is mode for file openning.

    read_image = open(image).read
    File.open('image.png', 'w+') do |file|
      file.write read_image
    end
    

    Your third variant works good. 5482 - length of file. File 'image.png' in same directory as your .rb file.