当前位置: 首页 > 知识库问答 >
问题:

Selenium WebDriver C#带有ChromeDriver和FirefoxDriver的完整网站截图

宗政永望
2023-03-14

当我用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中的实现略有不同。

我的问题是:

>

  • 为什么ChromeDriver和FirefoxDriver的之间有如此大的区别。GetScreenshot()方法,即使它们使用相同的界面(ITakesScreenshot)?

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

  • 共有3个答案

    卫梓
    2023-03-14

    ChromeDriver似乎还没有实现全屏截图,因为之前的实现中存在一些不准确之处。

    来源:https://code.google.com/p/chromedriver/issues/detail?id=294

    我最近编写了一个基于Selenium的应用程序来测试Internet Explorer UI,发现:

    1. 使用selenium拍摄屏幕截图的速度不如使用selenium快。NET和
    2. 当出现对话框时,Selenium无法截图。这是一个主要缺点,因为在与页面交互期间,我需要识别意外的对话框

    使用图形进行调查。系统中的CopyFromScreen方法。在Chrome中实现该功能之前,将绘图作为替代解决方案。一旦你尝试过。然而,我不认为你会回头看

    严阳秋
    2023-03-14

    我清理了@Selvantharajah Roshanth的答案,并添加了一个复选框,这样它就不会试图将已经适合视口的截图拼接在一起。

    public Image GetEntireScreenshot()
    {
        // Get the total size of the page
        var totalWidth = (int) (long) ((IJavaScriptExecutor) driver).ExecuteScript("return document.body.offsetWidth"); //documentElement.scrollWidth");
        var totalHeight = (int) (long) ((IJavaScriptExecutor) driver).ExecuteScript("return  document.body.parentNode.scrollHeight");
        // Get the size of the viewport
        var viewportWidth = (int) (long) ((IJavaScriptExecutor) driver).ExecuteScript("return document.body.clientWidth"); //documentElement.scrollWidth");
        var viewportHeight = (int) (long) ((IJavaScriptExecutor) driver).ExecuteScript("return window.innerHeight"); //documentElement.scrollWidth");
    
        // We only care about taking multiple images together if it doesn't already fit
        if (totalWidth <= viewportWidth && totalHeight <= viewportHeight)
        {
            var screenshot = driver.TakeScreenshot();
            return ScreenshotToImage(screenshot);
        }
        // Split the screen in multiple Rectangles
        var rectangles = new List<Rectangle>();
        // Loop until the totalHeight is reached
        for (var y = 0; y < totalHeight; y += viewportHeight)
        {
            var newHeight = viewportHeight;
            // Fix if the height of the element is too big
            if (y + viewportHeight > totalHeight)
            {
                newHeight = totalHeight - y;
            }
            // Loop until the totalWidth is reached
            for (var x = 0; x < totalWidth; x += viewportWidth)
            {
                var newWidth = viewportWidth;
                // Fix if the Width of the Element is too big
                if (x + viewportWidth > totalWidth)
                {
                    newWidth = totalWidth - x;
                }
                // Create and add the Rectangle
                var currRect = new Rectangle(x, y, newWidth, newHeight);
                rectangles.Add(currRect);
            }
        }
        // Build the Image
        var stitchedImage = new Bitmap(totalWidth, totalHeight);
        // Get all Screenshots and stitch them together
        var previous = Rectangle.Empty;
        foreach (var rectangle in rectangles)
        {
            // Calculate the scrolling (if needed)
            if (previous != Rectangle.Empty)
            {
                var xDiff = rectangle.Right - previous.Right;
                var yDiff = rectangle.Bottom - previous.Bottom;
                // Scroll
                ((IJavaScriptExecutor) driver).ExecuteScript(String.Format("window.scrollBy({0}, {1})", xDiff, yDiff));
            }
            // Take Screenshot
            var screenshot = driver.TakeScreenshot();
            // Build an Image out of the Screenshot
            var screenshotImage = ScreenshotToImage(screenshot);
            // Calculate the source Rectangle
            var sourceRectangle = new Rectangle(viewportWidth - rectangle.Width, viewportHeight - rectangle.Height, rectangle.Width, rectangle.Height);
            // Copy the Image
            using (var graphics = Graphics.FromImage(stitchedImage))
            {
                graphics.DrawImage(screenshotImage, rectangle, sourceRectangle, GraphicsUnit.Pixel);
            }
            // Set the Previous Rectangle
            previous = rectangle;
        }
        return stitchedImage;
    }
    
    private static Image ScreenshotToImage(Screenshot screenshot)
    {
        Image screenshotImage;
        using (var memStream = new MemoryStream(screenshot.AsByteArray))
        {
            screenshotImage = Image.FromStream(memStream);
        }
        return screenshotImage;
    }
    
    聂煜
    2023-03-14

    我们无法使用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;
        }
    
     类似资料:
    • 问题内容: 如何使用Selenium WebDriver 拍摄整个网页的屏幕快照( 全屏屏幕截图 ),而不仅仅是部分( 从上到下 )? 我的代码: ( Java绑定 ) 关于如何解决这个问题的任何想法? 问题答案: LE: 我看到很多人都对整页的截图感兴趣,所以我想我可能会用一些肯定的答案( 银色子弹 )来更新答案。 有很多Web测试框架可以( 只需最少的设置和工作 )即可生成 整页的屏幕截图 。

    • 问题内容: 我正在使用Spring MVC处理JSON POST请求。在幕后,我使用的是在Jackson JSON处理器上构建的MappingJacksonHttpMessageConverter,并在使用mvc:annotation驱动时启用了该功能。 我的一项服务收到了一系列操作: 我发现杰克逊将requestBody映射到java.util.LinkedHashMap项列表(简单数据绑定)。

    • 我还尝试了类似问题的其他答案所建议的runtime.getruntime()。那根本没用。有人能帮忙吗? 以下是控制台输出和堆栈跟踪(为了澄清(MyClass第114行位于行的位置):

    • 嗨,我如何在Windows电脑上使用任何浏览器拍摄网页的完整屏幕截图? 每当我用PrintScreen截图时,它只截图显示页面,但我希望截图的高度为整页。我们能拍完整的截图吗,包括隐藏的八张? 抱歉我英语不好。 我有firefox和chrome。

    • 我希望我的程序打开默认的chrome配置文件,然后获得YouTube。我可以让它打开youtube(在新的chrome浏览器中),或者打开默认的chrome配置文件,但不能两者兼而有之。(不,我没有运行两个驱动变量) 当我运行获取chrome配置文件的驱动程序行时,我会得到错误: 回溯(最近的调用为last):文件“C:\users\myname\onedrive\documents\python