简体   繁体   English

如何在 Ruby 中使用 selenium-webdriver/capybara 截取完整浏览器页面及其元素的屏幕截图?

[英]How to take a screenshot of a full browser page and its elements using selenium-webdriver/capybara in Ruby?

I am working on screenshot automation.我正在研究屏幕截图自动化。 In particular, I am trying to achieve the following:特别是,我正在努力实现以下目标:

  1. Prompt the user for the links to different pages on the website X提示用户链接到网站上的不同页面 X
  2. Prompt the user for the class name Y提示用户输入 class 名称 Y
  3. I should be able to visit a website X login page, provide login details (assume they are known), click on "submit" button, that should redirect me to the "home" page我应该能够访问网站 X 登录页面,提供登录详细信息(假设它们是已知的),单击“提交”按钮,这应该会将我重定向到“主页”页面
  4. Then I look at the list of links, provided by the user, visit each page and take screenshots of all elements, that have class Y (or the entire page)然后我查看用户提供的链接列表,访问每个页面并截取具有 class Y(或整个页面)的所有元素的屏幕截图
  5. Save them in the current directory将它们保存在当前目录中

Please click on the link for visual representation请点击链接查看视觉展示

I wanted to implement the following solution in Ruby (but I am also open to any other suggestions):我想在 Ruby 中实施以下解决方案(但我也愿意接受任何其他建议):

1) Take a screenshot of the entire scrollable page on the website X 2) Find the element(s) of class Y, in particular its location on the page, width and height. 1) 截取网站 X 上整个可滚动页面的屏幕截图 2) 找到 class Y 的元素,特别是它在页面上的位置、宽度和高度。 3) Crop the full screenshot so that only desired element is visible 3)裁剪完整的屏幕截图,以便只显示所需的元素

Problem is the following:问题如下:

I cannot take a screenshot of the entire page, I was only able to take a screenshot of the visible area of my screen.我无法截取整个页面的屏幕截图,我只能截取屏幕可见区域的屏幕截图。

This is what I tried and corresponding problems:这是我尝试过的以及相应的问题:

SOLUTION 1 (Ruby - General):解决方案 1(Ruby - 一般):

require 'selenium-webdriver'

driver = Selenium::WebDriver.for :firefox #:chrome

driver.navigate.to "https://some_very-very_long_page_on_website_X"
driver.manage.window.maximize # <- works for firefox only
driver.save_screenshot('picture1.png')

# Problem: it captures only the viewable area, 
# not an entire page

SOLUTION 2 (Ruby - Window Resizing):解决方案 2(Ruby - Window 调整大小):

require 'selenium-webdriver'

driver = Selenium::WebDriver.for :firefox #:chrome
driver.navigate.to 'https://some_very-very_long_page_on_website_X'

width  = driver.execute_script("return Math.max(document.body.scrollWidth,document.body.offsetWidth,document.documentElement.clientWidth,document.documentElement.scrollWidth,document.documentElement.offsetWidth);")
height = driver.execute_script("return Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight);")

driver.manage.window.resize_to(width, height) # <- resizes the window
driver.manage.window.full_screen  # <- works, but in chrome throws:
                                  # full_screen': undefined method `full_screen_window'

picture = driver.screenshot_as(:png)

File.open('picture2.png', 'w+') do |fh|
  fh.write picture
end

driver.quit

# Resizes the window only to the viewable area, as a result,
# it captures the viewable area only

SOLUTION 3 (Ruby- watir gem):解决方案 3(Ruby-watir 宝石):

require 'watir'

b = Watir::Browser.new
b.goto 'https://some_very-very_long_page_on_website_X'
b.screenshot.save("picture.png")

# Issues: does not capture the entire page

SOLUTION 4 (Ruby - Single element capturing)解决方案 4(Ruby - 单元素捕获)

require "selenium-webdriver"

driver = Selenium::WebDriver.for :chrome

driver.get'https://some_very-very_long_page_on_website_X'

driver.manage.window.maximize
driver.execute_script("document.getElementById('some_id').scrollIntoView();")
driver.save_screenshot "picture3.png"

# Problem: captures the element, which I need, but only if its size is less than
# the viewable area

SOLUTION 5 (Ruby - Zooming)解决方案 5(Ruby - 缩放)

require "selenium-webdriver"

driver = Selenium::WebDriver.for :firefox

driver.get 'https://some_very-very_long_page_on_website_X'

driver.manage.window.maximize
driver.execute_script("document.body.style.transform = 'scale(0.5)'")
#driver.execute_script("document.body.style.zoom = '50%'") <-- transform works better than zoom

driver.save_screenshot "picture3.png"

#Issues: works, but not for very long pages, in addition it may change the layout
# (some elements may start to overlap each other)
# Also I am not sure how to calculate the value of the parameter for scale
# for very long pages

SOLUTION 6 - (Ruby - Headless Chrome Resizing)解决方案 6 -(Ruby - 无头 Chrome 调整大小)

require "selenium-webdriver"

options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
driver = Selenium::WebDriver.for :chrome, options: options

driver.get "https://some_very-very_long_page_on_website_X"

width  = driver.execute_script("return Math.max(document.body.scrollWidth,document.body.offsetWidth,document.documentElement.clientWidth,document.documentElement.scrollWidth,document.documentElement.offsetWidth);")
height = driver.execute_script("return Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight);")

driver.manage.window.resize_to(width+2000, height+2000) # <-- if I do not have +2000, page looks squished
                                                        # the greater the number, the greater the quality
                                                        # but also the more white space is around the page
                                                        # and the picture is heavier
driver.manage.window.maximize

sleep 5             # <--- required waiting for page loading 
driver.save_screenshot "full.png"

# One of the best approaches, but it is not clear to me how to calculate 
# the parameters for resize_to

Tools/Technologies:工具/技术:

  • selenium-webdriver (3.12.0) selenium-webdriver (3.12.0)
  • ChromeDriver 2.40 Chrome 驱动程序 2.40

You can use the watir-screenshot-stitch gem to do exactly what you want:您可以使用watir-screenshot-stitch gem来完成您想要的操作:

require 'watir-screenshot-stitch'
b = Watir::Browser.new :firefox
b.goto "https://github.com/mozilla/geckodriver/issues/570"
b.base64_geckodriver # => returns a base64-encoded full page screenshot.

You can do so using Firefox and the "webdrivers" gem, which installs "selenium-webdriver" as a dependency:您可以使用 Firefox 和"webdrivers" gem 来执行此操作,它将"selenium-webdriver"安装为依赖项:

require "webdrivers/geckodriver"

driver = Selenium::WebDriver.for :firefox
driver.get("https://openai.com/api/")
File.binwrite("screenshot.png", driver.screenshot_as(:png, full_page: true))
driver.quit

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Selenium-WebDriver 如何使用 javascript 和 firefox 浏览器突出显示元素 - Selenium-WebDriver how to highlight element using javascript and firefox browser 用于解析的Selenium-webdriver(Ruby) - Selenium-webdriver for parsing (Ruby) 我正在尝试使用selenium-webdriver拍摄元素的屏幕截图,但是抛出了UnsupportedOperationError吗? - I'm trying to take a screenshot of an element with selenium-webdriver, but UnsupportedOperationError was thrown? Selenium-webdriver / Javascript:如何滚动页面? - Selenium-webdriver/Javascript: How do I scroll through a page? 如何使用 webdriverIO 命令截取完整的 web 页面截图? - How to take full web page screenshot using webdriverIO command? 如何使用selenium-webdriver正确添加cookie? - How can I correctly add a cookie using selenium-webdriver? 如何在 Chrome 中使用 Selenium-Webdriver for JavaScript 接受不安全的证书? - How to accept insecure certificates in Chrome using Selenium-Webdriver for JavaScript? Selenium - 使用 NodeJS 中的 selenium-webdriver 库与现有浏览器会话交互 - Selenium - Interact with exsting browser session using selenium-webdriver library in NodeJS 如何在Selenium-WebDriver中禁用Promise Manager - How to disable promise manager in selenium-webdriver 如何更新 selenium-webdriver 的版本? - How to update selenium-webdriver's version?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM