【问题标题】:Capybara: save image from loaded page (not screenshot)Capybara:从加载的页面保存图像(不是截图)
【发布时间】:2018-03-01 03:10:05
【问题描述】:

我正在使用红宝石和水豚宝石。我的意思是加载一个页面,保存一个图像,然后用它做一些事情。网页地址相同,但每次重新加载页面时图像不同,实际上是验证码。

我正在尝试保存该页面中的图像。在这种情况下,使用 save_page 保存的屏幕截图不适合我。

下面请看我使用的代码:

require 'capybara'
requre 'capybara/dsl'
require 'pry'

Capybara.register_driver :selenium_chrome do |app|
  Capybara::Selenium::Driver.new(app, :browser => :chrome)
end

Capybara.run_server = false
Capybara.current_driver = :selenium_chrome
Capybara.app_host = "some-site"

module MyCapybara
  class Crawler
    include Capybara::DSL
  end
end

c = MyCapybara::Crawler.new
c.visit('some-url')

# [21] pry(main)> c.inspect
# => "#<MyCapybara::Crawler:0x007fc999c21d60>"

i = c.find_by_id('captcha').find('img')

# [23] pry(main)> i.inspect
# => "#<Capybara::Node::Element tag=\"img\" path=\"/html/body/div/div[2]/div[1]/div[1]/form/div[1]/img\">"

binding.pry

puts 1

我需要将图像“包含”保存在i 中。使用其他工具通过 url 获取它将不起作用,因为不同的图像每次都有相同的 url .../captcha.jpg

我无法提供确切的网站和屏幕截图,对此深表歉意。

有人可以帮我解决这个问题吗?或者我为此选择了不合适的工具(我的意思是 Capybara),更好的是尝试 Mechanize gem?

谢谢!

解决方案

请看下面我用来保存图片的js:

// captcha_fetcher.js

(function () {
  var form = document.getElementById("appointment_captcha_month");
  var img = form.getElementsByTagName("img")[0];

  var canvas = document.createElement("canvas");
  canvas.width = img.width;
  canvas.height = img.height;

  var ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0);

  var dataURL = canvas.toDataURL("image/png");

  return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}())

然后通过evaluate_script调用这个:

image_base64_encoded = page.evaluate_script(IO.read('captcha_fetcher.js'))

【问题讨论】:

  • Capybara 没有内置方法,但您可以执行 javasscript 将 drawImage(i) 放入画布元素并使用 getImageData 从画布获取像素值并写入一个外部文件。如果 Mechanize 有办法保存图像,它可能会更容易。
  • 感谢您的评论!我已经使用 c.page.execute_script(...) 执行了 js,它返回给我 base64 编码的图像。
  • 如果你要返回东西,你可能想要使用 evaluate_script -- 从技术上讲,execute_script 被定义为不返回任何内容,因此它可以随时更改
  • 我将我的评论复制到一个答案中,以便您将其标记为关闭
  • 是的,#evaluate_script 是对的。另外,我遇​​到了 CORS 问题,但在 url 中切换到 HTTPS 解决了这个问题。感谢您的帮助。

标签: ruby capybara


【解决方案1】:

Capybara 没有内置方法,但您可以执行 javascript (page.evaluate_script) 将 drawImage(i) 放入画布元素,然后使用 getImageData 从画布获取像素值并写入一个外部文件。

【讨论】:

    【解决方案2】:

    我遇到了您的问题,并开始按照 Thomas Walpole 和 Igor 的建议整合一个 javascript 解决方案。看起来很乱,所以我想出了这个:

    # Get the image source URL
    image_url = find_by_id('captcha').find('img')[:src]
    
    # Open the image in a new window
    image_window = session.open_new_window
    session.switch_to_window(image_window)
    
    # Take a screenshot of the new image and print it's path
    p session.save_screenshot
    

    【讨论】:

    • 感谢您在这么长时间后查看此主题。我无法测试您的解决方案,但请查看帖子的更新,我包含了我当时使用的完整解决方案。
    猜你喜欢
    • 2011-03-01
    • 1970-01-01
    • 2017-11-03
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-15
    相关资源
    最近更新 更多