You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Watir、geckodriver与Firefox截取全页面截图?

嘿,我之前升级Watir和Firefox后也碰到过这个糟心的问题——默认截图只截视口,geckodriver的全页API又遥遥无期。不过折腾了一阵,找到了两个不用回滚环境的办法,分享给你:

方案一:滚动分段截图+拼接(最可靠)

这个方法的核心思路是模拟人工滚动页面,每次截取当前视口的截图,最后用图片处理工具把所有截图垂直拼接起来。刚好你已经在用MiniMagick,完美适配这个方案。

具体代码实现如下:

require 'watir'
require 'mini_magick'
require 'base64'

def full_page_screenshot(browser)
  # 获取页面基础参数(适配Retina屏的分辨率加倍)
  viewport_height = browser.execute_script("return window.innerHeight")
  total_height = browser.execute_script("return document.documentElement.scrollHeight")
  # 计算Retina屏幕的缩放系数
  scale_factor = browser.screenshot.base64.size / (browser.execute_script("return window.innerWidth * window.innerHeight * 4").to_f)

  screenshots = []
  current_y = 0

  while current_y < total_height
    # 滚动到当前目标位置
    browser.execute_script("window.scrollTo(0, #{current_y});")
    # 等待页面滚动后加载稳定(可根据页面加载速度调整时长)
    sleep 0.5
    # 截取当前视口的截图并保存
    blob = Base64.decode64(browser.screenshot.base64)
    screenshots << MiniMagick::Image.read(blob)
    # 计算下一次滚动的位置,避免重复截取顶部内容
    current_y += viewport_height
  end

  # 创建空白的拼接画布
  combined_image = MiniMagick::Image.new(screenshots[0].width, (total_height * scale_factor).to_i) do |img|
    img.background 'white'
  end

  current_y_offset = 0
  screenshots.each_with_index do |img, index|
    # 最后一张截图可能不需要截满视口,自动裁剪到剩余页面高度
    img_height = if index == screenshots.length - 1
                   ((total_height - (current_y_offset / scale_factor)) * scale_factor).to_i
                 else
                   img.height
                 end
    # 将当前截图拼接到画布上
    combined_image = combined_image.composite(img) do |c|
      c.compose 'over'
      c.geometry "+0+#{current_y_offset}"
      c.crop "0x#{img_height}+0+0"
    end
    current_y_offset += img_height
  end

  combined_image
end

# 使用示例
b = Watir::Browser.new :firefox
b.goto "https://daringfireball.net"
full_image = full_page_screenshot(b)
full_image.write "full_page.png"
b.quit

注意事项:

  • 加入了sleep等待页面滚动稳定,避免出现空白或加载不全的截图,你可以根据页面实际加载速度调整时长。
  • 自动适配了Retina屏的分辨率缩放问题,确保拼接后的图片高度和实际页面一致。
  • 最后一张截图会自动裁剪到剩余页面高度,避免出现多余空白。

方案二:临时调整浏览器窗口高度(简单但有局限)

如果你的页面高度不是特别夸张(没有超过浏览器允许的最大窗口高度),可以直接把浏览器窗口的高度设置为页面的总滚动高度,此时视口就等于整个页面,直接截图即可。

代码示例:

require 'watir'
require 'mini_magick'
require 'base64'

b = Watir::Browser.new :firefox
b.goto "https://daringfireball.net"

# 获取页面总高度和当前窗口宽度
page_height = b.execute_script("return document.documentElement.scrollHeight")
current_width = b.driver.manage.window.size.width

# 调整窗口高度为页面总高度(部分系统/浏览器对窗口高度有上限)
b.driver.manage.window.resize_to(current_width, page_height)

# 等待窗口调整完成
sleep 0.5

# 此时截图就是全页面内容
blob = Base64.decode64(b.screenshot.base64)
image = MiniMagick::Image.read(blob)
image.write "full_page_simple.png"

b.quit

局限性:

  • 很多浏览器(比如macOS上的Firefox)对窗口高度有上限,不能超过屏幕最大高度,超长页面会失效。
  • 部分页面的元素布局依赖窗口大小,调整窗口高度可能导致页面布局变形,影响截图效果。

两个方案里,我个人更推荐第一个,虽然代码多一点,但兼容性和可靠性都更高,不管页面多长都能搞定。

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:50:53