Selenium WebDriver C# 使用 ChromeDriver 和 FirefoxDriver 的完整网站屏幕截图

2024-02-22

当我使用 ChromeDriver 截取屏幕截图时,我会得到与我的视口大小相同的屏幕。
当我使用 FirefoxDriver 截取屏幕截图时,我得到了我想要的,即网站的全屏打印。

ChromeDriver 声明如下:

IWebDriver driver = new ChromeDriver();

FirefoxDriver 声明如下:

IWebDriver driver = new FirefoxDriver();

两个驱动程序执行相同的代码:

driver.Manage().Window.Maximize();
driver.Navigate().GoToUrl(url);//url is a string variable
ITakesScreenshot screenshotDriver = driver as ITakesScreenshot;
Screenshot screenshot = screenshotDriver.GetScreenshot();
screenshot.SaveAsFile("c:/test.png", ImageFormat.Png);

ChromeDriver 的 test.png 分辨率为 1920x1099,仅包含浏览器视口。
FirefoxDriver 的 test.png 分辨率为 1903x16559,包含整个页面。

我知道GetScreenshot()方法不会返回相同的分辨率大小,因为它在 IEDriver、FirefoxDriver、OperaDriver、ChromeDriver 中的实现略有不同。

我的问题是:

  1. 为什么 ChromeDriver 和 FirefoxDriver 之间有如此大的差异.GetScreenshot()方法,即使它们使用相同的界面(ITakesScreenshot)?

  2. 有没有办法让ChromeDriver的GetScreenshot()方法返回整个网页屏幕而不仅仅是视口?


我们无法使用ChromeDriver2获取整个页面的屏幕截图,我们需要手动实现。我修改了博客中可用的方法,该方法与ChromeDriver配合良好。

使用此方法如下:

private IWebDriver _driver = new ChromeDriver(CHROME_DRIVER_PATH);
screenshot.SaveAsFile(saveFileName, ImageFormat.Jpeg);

public Bitmap GetEntereScreenshot()
    {

        Bitmap stitchedImage = null;
        try
        {
            long totalwidth1 = (long)((IJavaScriptExecutor)_driver).ExecuteScript("return document.body.offsetWidth");//documentElement.scrollWidth");

            long totalHeight1 = (long)((IJavaScriptExecutor)_driver).ExecuteScript("return  document.body.parentNode.scrollHeight");

            int totalWidth = (int)totalwidth1;
            int totalHeight = (int)totalHeight1;

            // Get the Size of the Viewport
            long viewportWidth1 = (long)((IJavaScriptExecutor)_driver).ExecuteScript("return document.body.clientWidth");//documentElement.scrollWidth");
            long viewportHeight1 = (long)((IJavaScriptExecutor)_driver).ExecuteScript("return window.innerHeight");//documentElement.scrollWidth");

            int viewportWidth = (int)viewportWidth1;
            int viewportHeight = (int)viewportHeight1;


        // Split the Screen in multiple Rectangles
        List<Rectangle> rectangles = new List<Rectangle>();
        // Loop until the Total Height is reached
        for (int i = 0; i < totalHeight; i += viewportHeight)
        {
            int newHeight = viewportHeight;
            // Fix if the Height of the Element is too big
            if (i + viewportHeight > totalHeight)
            {
                newHeight = totalHeight - i;
            }
            // Loop until the Total Width is reached
            for (int ii = 0; ii < totalWidth; ii += viewportWidth)
            {
                int newWidth = viewportWidth;
                // Fix if the Width of the Element is too big
                if (ii + viewportWidth > totalWidth)
                {
                    newWidth = totalWidth - ii;
                }

                // Create and add the Rectangle
                Rectangle currRect = new Rectangle(ii, i, newWidth, newHeight);
                rectangles.Add(currRect);
            }
        }

        // Build the Image
        stitchedImage = new Bitmap(totalWidth, totalHeight);
        // Get all Screenshots and stitch them together
        Rectangle previous = Rectangle.Empty;
        foreach (var rectangle in rectangles)
        {
            // Calculate the Scrolling (if needed)
            if (previous != Rectangle.Empty)
            {
                int xDiff = rectangle.Right - previous.Right;
                int yDiff = rectangle.Bottom - previous.Bottom;
                // Scroll
                //selenium.RunScript(String.Format("window.scrollBy({0}, {1})", xDiff, yDiff));
                ((IJavaScriptExecutor)_driver).ExecuteScript(String.Format("window.scrollBy({0}, {1})", xDiff, yDiff));
                System.Threading.Thread.Sleep(200);
            }

            // Take Screenshot
            var screenshot = ((ITakesScreenshot)_driver).GetScreenshot();

            // Build an Image out of the Screenshot
            Image screenshotImage;
            using (MemoryStream memStream = new MemoryStream(screenshot.AsByteArray))
            {
                screenshotImage = Image.FromStream(memStream);
            }

            // Calculate the Source Rectangle
            Rectangle sourceRectangle = new Rectangle(viewportWidth - rectangle.Width, viewportHeight - rectangle.Height, rectangle.Width, rectangle.Height);

            // Copy the Image
            using (Graphics g = Graphics.FromImage(stitchedImage))
            {
                g.DrawImage(screenshotImage, rectangle, sourceRectangle, GraphicsUnit.Pixel);
            }

            // Set the Previous Rectangle
            previous = rectangle;
        }
        }
        catch (Exception ex)
        {
            // handle
        }
        return stitchedImage;
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Selenium WebDriver C# 使用 ChromeDriver 和 FirefoxDriver 的完整网站屏幕截图 的相关文章

随机推荐

  • 为什么 Bootstrap-3 中没有 col-xs-offset-* 类?

    我读到Twitter Bootstrap 3 文档 http getbootstrap com css grid offsetting它不支持col xs offset 类 这似乎不符合移动优先 有充分的理由吗 我认为它们可能有用 I re
  • Bootstrap 图标栏未显示

    调整浏览器大小时 Bootstrap 导航栏菜单中的图标栏不显示 http jsbin com ixAqinA 1 http jsbin com ixAqinA 1 section class container div class nav
  • 如何显示当前文件上传的缩略图或预览

    我无法显示预览video image being loaded 基本上我的意思是说下面的代码不是firing to get video image preview 这是我的Jsfiddle http jsfiddle net ChJ9B 1
  • 不同的 CSS 背景图像取决于月份和年份

    基本上 我有一个带有文本的 div 我希望背景根据月份和年份显示不同的图像 我怎样才能实现这个目标 任何帮助将不胜感激 我已经准备了 4 年的每月图像 标记为 month0 2011 png 到 month11 2014 png 如果有帮助
  • HttpListener:如何获取http用户和密码?

    我在这里遇到了 HttpListener 的问题 当表单请求 http user email protected cdn cgi l email protection 制作完成后 如何获取用户名和密码 HttpWebRequest 有一个
  • 静态 boost::wregex 实例是线程安全的吗?

    使用固定的 boost wregex 声明静态 全局变量 然后从多个线程使用它 而不用担心正则表达式的内部状态 如果 Boost 已使用 BOOST HAS THREADS 进行编译 是否安全 e g boost wregex g rege
  • 通过 Hibernate 获取 PL/SQL 函数的返回值

    我在 Oracle 数据库中有一个无法更改的 PL SQL 函数 该函数采用一个标识实体的参数 创建该实体的副本 然后返回副本的 ID 这看起来像 函数 copy entity id IN NUMBER 返回号码 我需要从 Hibernat
  • 混合 C++ 异常处理和 SEH (Windows)

    我有一个函数 我在其中调用getaddrinfo 得到一个sockaddr 其目标内存是由系统分配的 许多人可能知道 您需要致电freeaddrinfo 释放由 getaddrinfo 分配的内存 现在 在我的函数中 有几个地方可能会抛出异
  • 带 && 的 C if 语句 - 哪个函数将首先执行?

    如果我在 C 中有一个 if 语句 如下所示 if function1 gt 0 function2 gt 0 blah 哪个函数将首先执行并且总是按该顺序执行 Here function1 is 保证首先执行 The 运算符是一个短路运算
  • 向量的一维卷积

    我正在学习如何使用具有一维卷积的卷积神经网络 这是一个家庭作业示例 import numpy as np import keras from keras models import Sequential from keras layers
  • 为什么 parseInt(1/0, 19) 返回 18?

    我有一个恼人的问题JavaScript gt parseInt 1 0 19 gt 18 为什么parseInt函数返回18 的结果1 0 is Infinity https developer mozilla org en US docs
  • 如何在 SSIS 中设置 zip 文件的密码?

    我使用 SSIS 中的执行进程任务通过 7 zip 压缩了文件 现在我必须为 zip 文件设置密码 我该如何实现 我不认为这是一个 ssis 问题 你必须看看7zip 命令行用户指南 https sevenzip osdn jp chm c
  • 我如何告诉 Struts2 在表单第一次显示时不要验证表单?

    我目前正在尝试学习Struts2 我创建了一个表单 一个处理表单的操作 一个验证表单的 XML 以及 struts xml 中的操作 每次显示表单时 即使是第一次 Struts2 都会尝试进行验证 因此在用户有机会完成表单之前就会显示错误
  • Chai 无法识别内容类型“application/javascript”

    无论我的服务器实际返回什么 Chai 总是给我res body 如果内容类型是 application javascript 这是我的服务器 const http require http const server http createS
  • 在 Go 中将 unicode 代码点转换为文字字符

    假设我有一个这样的文本文件 u0053 u0075 u006E 有什么方法可以将其转换为这个吗 S u n 目前 我正在使用ioutil ReadFile data txt 但是当我打印数据时 我得到的是 unicode 代码点而不是字符串
  • WSO2 身份服务器外部 LDAP 因 OID 身份人员不存在而抛出 OBJECT_CLASS

    我正在使用 Identity Server 4 1 0 并且还在 Apache Directory Studio 中运行 ApacheDS 所以我现在想要的是将我的 IS 连接到外部 LDAP IS 与 ldap 的连接良好 只是由于缺少属
  • 多个事件的 Gmail 标记

    我正在使用 json ld 开发事件标记 以包含在确认电子邮件中 我的一些事件会定期重复发生 但是 最新的 Schema org 规范不支持重复事件 因此我遵循了此处提供的建议 http lists w3 org Archives Publ
  • ORACLE/ASP.NET:ORA-2020 - 数据库链接太多......是什么原因造成的?

    这是场景 我们有一个运行最新版本 ODAC Oracle 客户端 的内部网站 它打开数据库连接 运行存储过程或打包方法 然后断开连接 连接池已打开 目前我们的开发和测试环境均处于 11g 版本 但生产环境处于 10gR2 版本 这种情况发生
  • 从 IE 中 HtmlElement 的 Dom 获取 IHTMLStyle3

    我在窗体上有一个 System Windows Form WebBrowser 控件 我将该浏览器对象导航到一个网址 页面加载完成后 我想分析加载的页面的各个方面 我特别感兴趣的是在 IHTMLStyle3 接口上找到的属性 writing
  • Selenium WebDriver C# 使用 ChromeDriver 和 FirefoxDriver 的完整网站屏幕截图

    当我使用 ChromeDriver 截取屏幕截图时 我会得到与我的视口大小相同的屏幕 当我使用 FirefoxDriver 截取屏幕截图时 我得到了我想要的 即网站的全屏打印 ChromeDriver 声明如下 IWebDriver dri