【发布时间】: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 解决了这个问题。感谢您的帮助。