87 votes

Comment capturer la capture d'écran d'un élément spécifique plutôt que de la page entière en utilisant Selenium Webdriver ?

Actuellement, j'essaie de capturer une capture d'écran en utilisant le Selenium WebDriver. Mais je ne peux obtenir que la capture d'écran de la page entière. Cependant, ce que je voulais, c'était juste capturer une partie de la page ou peut-être juste un élément spécifique basé sur l'ID ou tout autre localisateur d'élément spécifique. (Par exemple, je souhaite capturer l'image avec image id = "Butterfly")

Existe-t-il un moyen de capturer une capture d'écran par élément ou élément sélectionné ?

5voto

J'ai perdu beaucoup de temps à faire des captures d'écran et je veux sauver les vôtres. J'ai utilisé chrome + selenium + c# le résultat était totalement horrible. Finalement j'ai écrit une fonction :

driver.Manage().Window.Maximize();
             RemoteWebElement remElement = (RemoteWebElement)driver.FindElement(By.Id("submit-button")); 
             Point location = remElement.LocationOnScreenOnceScrolledIntoView;  

             int viewportWidth = Convert.ToInt32(((IJavaScriptExecutor)driver).ExecuteScript("return document.documentElement.clientWidth"));
             int viewportHeight = Convert.ToInt32(((IJavaScriptExecutor)driver).ExecuteScript("return document.documentElement.clientHeight"));

             driver.SwitchTo();

             int elementLocation_X = location.X;
             int elementLocation_Y = location.Y;

             IWebElement img = driver.FindElement(By.Id("submit-button"));

             int elementSize_Width = img.Size.Width;
             int elementSize_Height = img.Size.Height;

             Size s = new Size();
             s.Width = driver.Manage().Window.Size.Width;
             s.Height = driver.Manage().Window.Size.Height;

             Bitmap bitmap = new Bitmap(s.Width, s.Height);
             Graphics graphics = Graphics.FromImage(bitmap as Image);
             graphics.CopyFromScreen(0, 0, 0, 0, s);

             bitmap.Save(filePath, System.Drawing.Imaging.ImageFormat.Png);

             RectangleF part = new RectangleF(elementLocation_X, elementLocation_Y + (s.Height - viewportHeight), elementSize_Width, elementSize_Height);

             Bitmap bmpobj = (Bitmap)Image.FromFile(filePath);
             Bitmap bn = bmpobj.Clone(part, bmpobj.PixelFormat);
             bn.Save(finalPictureFilePath, System.Drawing.Imaging.ImageFormat.Png);

5voto

rath Points 703

Réponse de Surya fonctionne très bien si vous n'avez pas peur d'impliquer des entrées-sorties de disque. Si vous ne préférez pas, cette méthode vous conviendra peut-être mieux.

private Image getScreenshot(final WebDriver d, final WebElement e) throws IOException {
    final BufferedImage img;
    final Point topleft;
    final Point bottomright;

    final byte[] screengrab;
    screengrab = ((TakesScreenshot) d).getScreenshotAs(OutputType.BYTES);

    img = ImageIO.read(new ByteArrayInputStream(screengrab));

    //crop the image to focus on e
    //get dimensions (crop points)
    topleft = e.getLocation();
    bottomright = new Point(e.getSize().getWidth(),
                            e.getSize().getHeight());

    return img.getSubimage(topleft.getX(),
                           topleft.getY(),
                           bottomright.getX(),
                           bottomright.getY());
}

Si vous préférez, vous pouvez éviter de déclarer screengrab et de faire plutôt

img = ImageIO.read(
    new ByteArrayInputStream(
        ((TakesScreenshot) d).getScreenshotAs(OutputType.BYTES)));

ce qui est plus propre, mais je l'ai laissé pour plus de clarté. Vous pouvez alors l'enregistrer dans un fichier ou le mettre dans un JPanel à votre guise.

5voto

Lorenzo Points 320

Je pense que la plupart des réponses ici sont sur-engagées. La façon dont je l'ai fait est à travers 2 méthodes d'aide, la première pour attendre un élément basé sur n'importe quel sélecteur ; et la seconde pour prendre une capture d'écran de celui-ci.

Note : Nous avons lancé le WebElement à un TakesScreenshot de sorte que nous ne capturons que cet élément dans l'image spécifiquement. Si vous voulez la page/fenêtre complète, vous devez lancer driver à la place.

Edit : J'ai oublié de dire que j'utilise Java et Selenium v3 (mais cela devrait être la même chose pour v4).

WebDriver driver = new FirefoxDriver(); // define this somewhere (or chrome etc)

public <T> T screenshotOf(By by, long timeout, OutputType<T> type) {
    return ((TakesScreenshot) waitForElement(by, timeout))
            .getScreenshotAs(type);
}

public WebElement waitForElement(By by, long timeout) {
    return new WebDriverWait(driver, timeout)
            .until(driver -> driver.findElement(by));
}

Et ensuite, faites une capture d'écran de ce que vous voulez comme ceci :

long timeout = 5;   // in seconds
/* Screenshot (to file) based on first occurence of tag */
File sc = screenshotOf(By.tagName("body"), timeout, OutputType.FILE); 
/* Screenshot (in memory) based on CSS selector (e.g. first image in body
who's "src" attribute starts with "https")  */
byte[] sc = screenshotOf(By.cssSelector("body > img[href^='https']"), timeout, OutputType.BYTES);

4voto

rovr138 Points 372

Python 3

Essayé avec Selenium 3.141.0 et chromedriver 73.0.3683.68, cela fonctionne,

from selenium import webdriver

chromedriver = '/usr/local/bin/chromedriver'
chromeOptions = webdriver.ChromeOptions()
chromeOptions.add_argument('window-size=1366x768')
chromeOptions.add_argument('disable-extensions')
cdriver = webdriver.Chrome(options=chromeOptions, executable_path=chromedriver)

cdriver.get('url')
element = cdriver.find_element_by_css_selector('.some-css.selector')

element.screenshot_as_png('elemenent.png')

Il n'est pas nécessaire d'obtenir une image complète et d'obtenir une section d'une image plein écran.

Cela n'était peut-être pas disponible lorsque La réponse de Rohit a été créé.

2voto

Waqar Ullah Khan Points 111
public void GenerateSnapshot(string url, string selector, string filePath)
    {
        using (IWebDriver driver = new ChromeDriver())
        {
            driver.Navigate().GoToUrl(url);
            var remElement = driver.FindElement(By.CssSelector(selector));
            Point location = remElement.Location;

            var screenshot = (driver as ChromeDriver).GetScreenshot();
            using (MemoryStream stream = new MemoryStream(screenshot.AsByteArray))
            {
                using (Bitmap bitmap = new Bitmap(stream))
                {
                    RectangleF part = new RectangleF(location.X, location.Y, remElement.Size.Width, remElement.Size.Height);
                    using (Bitmap bn = bitmap.Clone(part, bitmap.PixelFormat))
                    {
                        bn.Save(filePath, System.Drawing.Imaging.ImageFormat.Png);
                    }
                }
            }
            driver.Close();
        }
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X