rubycdp / ferrum

Headless Chrome Ruby API
https://ferrum.rubycdp.com
MIT License
1.7k stars 122 forks source link

blank screenshot with selector #334

Closed zsan closed 1 year ago

zsan commented 1 year ago

Hello,

So i have this script

browser = Ferrum::Browser.new(headless: false, timeout: 120)
vnm_url = "secret_url"

browser.goto(vnm_url)
browser.at_css(".captcha").scroll_into_view
browser.screenshot(selector: ".captcha", path: "captcha.png")

And i saw that i only have blank image with white background

So my workaround is using browser.network.intercept

Its like

browser = Ferrum::Browser.new(headless: false, timeout: 120)

browser.network.intercept
browser.on(:request) do |request|
  if request.match?(/p_p_id=khaithithucdientu_WAR_eVisaportlet&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_cacheability=cacheLevelPage&p_p_col_id=column-2&p_p_col_count=1&_khaithithucdientu_WAR_eVisaportlet_view=insert/)
    response = Net::HTTP.get_response(URI(request.url))
    File.open("captcha.png", "wb") {|file| file.write(response.body) }
    request.continue
  else
    request.continue
  end
end

But i am curious :=) I calculated the position of the image with different method

captcha_el = browser.at_css(".captcha")
captcha_el.scroll_into_view
my_own_rect = captcha_el.evaluate("(function(el) { return { x: el.offsetLeft, y: el.offsetTop, width: el.offsetWidth, height: el.offsetHeight } })(this)")

(Btw i am not JS programmer, its like guessing game for me :))

Inspired by #285 (@route said that maybe we could try to pass area arguments right to the method) so i just changed method screenshot_options like this

require "ferrum"

module Ferrum
  class Page
    module Screenshot
      private

      def screenshot_options(path = nil, format: nil, scale: 1.0, **options)
        screenshot_options = {}

        format, quality = format_options(format, path, options[:quality])
        screenshot_options.merge!(quality: quality) if quality
        screenshot_options.merge!(format: format)

        clip = if options[:rect]
          options[:rect].merge(scale: scale)
        else
          area_options(options[:full], options[:selector], scale)
        end
        screenshot_options.merge!(clip: clip) if clip

        screenshot_options
      end
    end
  end
end

browser = Ferrum::Browser.new(headless: false, timeout: 120)

vnm_url = "secret_url"

browser.goto(vnm_url)
captcha_el = browser.at_css(".captcha")
captcha_el.scroll_into_view
my_own_rect = captcha_el.evaluate("(function(el) { return { x: el.offsetLeft, y: el.offsetTop, width: el.offsetWidth, height: el.offsetHeight } })(this)")

browser.screenshot(rect: my_own_rect, path: "captcha.png")

And seems now i can get the image