可以使用selenium的WebDriver将指定元素截图吗?

Posted 街头小贩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可以使用selenium的WebDriver将指定元素截图吗?相关的知识,希望对你有一定的参考价值。

项目有个小功能:为指定文章生成一份分享海报,看到WordPress的海报插件按捺不住了开工了。这里主要讲使用selenium框架来实现,不讲其它方案或框架。开动吧

引入maven依赖

		<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-firefox-driver -->
		<dependency>
			<groupId>org.seleniumhq.selenium</groupId>
			<artifactId>selenium-firefox-driver</artifactId>
			<version>3.141.59</version>
		</dependency>

最终会下载以下jar包

写个Test

	@Test 
	public void savesreen() throws IOException 
	    //有问题的代码不要复制使用
		WebDriver driver = new FirefoxDriver();
		driver.get("http://www.test.com/topic/poster?topic=91");
		WebElement ele = driver.findElement(By.id("poster")); //driver.findElement(By.tagName("body"));
		Rectangle rect = ele.getRect();
		// Get entire page screenshot
		File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
		BufferedImage fullImg = ImageIO.read(screenshot);
		BufferedImage eleScreenshot= fullImg.getSubimage(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
		File posterShot = File.createTempFile("20191219", "png");
		ImageIO.write(eleScreenshot, "png", posterShot);

		// Copy the element screenshot to disk
		File screenshotLocation = new File("C:\\\\qq_screenshot.png");
		FileUtils.copyFile(posterShot, screenshotLocation);
		driver.quit();
	

以上代码是有问题,不要复制使用,为哈要写呢?主要是讲下面的异常:

The path to the driver executable must be set by the webdriver.gecko.driver system property; for more information, see https://github.com/mozilla/geckodriver.

java.lang.IllegalStateException: The path to the driver executable must be set by the webdriver.gecko.driver system property; for more information, see https://github.com/mozilla/geckodriver. The latest version can be downloaded from https://github.com/mozilla/geckodriver/releases
	at com.google.common.base.Preconditions.checkState(Preconditions.java:847)
	at org.openqa.selenium.remote.service.DriverService.findExecutable(DriverService.java:134)
	at org.openqa.selenium.firefox.GeckoDriverService.access$100(GeckoDriverService.java:44)
	at org.openqa.selenium.firefox.GeckoDriverService$Builder.findDefaultExecutable(GeckoDriverService.java:167)
	at org.openqa.selenium.remote.service.DriverService$Builder.build(DriverService.java:355)
	at org.openqa.selenium.firefox.FirefoxDriver.toExecutor(FirefoxDriver.java:190)
	at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:147)
	at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:125)
	...

异常是说需要调置一个系统参数:webdriver.gecko.driver, 参数指向的文件可以去https://github.com/mozilla/geckodriver下载。好去下载并设置

	@Test 
	public void savesreen() throws IOException 
	    //有问题的代码不要复制使用
	    System.setProperty("webdriver.gecko.driver","C:\\\\geckodriver-v0.26.0\\\\geckodriver.exe");
		WebDriver driver = new FirefoxDriver();
		//ETC 其它代码不动
	

需要注意的是配合firefox的版本与selenium的版本,这个在//firefox-source-docs.mozilla.org/testing/geckodriver/有说明。

org.openqa.selenium.WebDriverException: Timed out waiting 45 seconds for Firefox to start.

org.openqa.selenium.WebDriverException: Timed out waiting 45 seconds for Firefox to start.
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'DESKTOP-QTAURUN', ip: '10.0.0.4', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_231'
Driver info: driver.version: FirefoxDriver
	at org.openqa.selenium.firefox.XpiDriverService.waitUntilAvailable(XpiDriverService.java:247)
	at org.openqa.selenium.firefox.XpiDriverService.start(XpiDriverService.java:159)
	at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:79)
	at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
	at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:213)
	at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:131)
	at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:147)
	at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:125)

也有可能出现这个异常,可能你是从网上复制的以下代码

System.setProperty(“webdriver.firefox.marionette”,“C:\\geckodriver-v0.26.0\\geckodriver.exe”);

这里提示一下多看错误提示,不要盲目复制。正常时RUN后会打开Firefox浏览器,浏览器的地址栏上会有get的URL.

浏览器也打开了,地址也出现在地址栏中但并没有生成图片


卡在W3C这,一直没有继续下去。一下午的反复运行发现总结有可能这几种情况

1)保存的位置没有写权限

File screenshotLocation = new File(“C:\\qq_screenshot.png”);

windows 10 可能对C盘有权限限制。

2)截取的坐标超出了原图的范围

例:原图的高度只有700多px, 而截取的y坐标大于700

进入正题

先看可以用的代码:

	@Test 
	public void savesreen() throws IOException 
		System.setProperty("webdriver.gecko.driver","C:\\\\geckodriver-v0.26.0\\\\geckodriver.exe");
		//
		FirefoxOptions options = new FirefoxOptions().setProfile(new FirefoxProfile());
		WebDriver driver = new FirefoxDriver(options);
		driver.manage().window().setSize(new Dimension(1920,1200)); //new Dimension(1024,768)|new Dimension(1440,900)
		//
		driver.get("http://www.test.com/topic/poster?topic=91");
		WebElement ele = driver.findElement(By.id("poster")); 
		Rectangle rect = ele.getRect();
		System.out.println("coordinate x: "+rect.getX()+", coordinate y: "+rect.getY());
		System.out.println("Rectangle width: "+rect.getWidth()+", Rectangle height: "+rect.getHeight());
		
		// Get entire page screenshot
		File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
		BufferedImage fullImg = ImageIO.read(screenshot);
		
		BufferedImage eleScreenshot= fullImg.getSubimage(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
		File posterShot = File.createTempFile("20191219", "png");
		ImageIO.write(eleScreenshot, "png", posterShot);

		// Copy the element screenshot to disk
		File screenshotLocation = new File("C:\\\\home\\\\admin\\\\qq_screenshot.png");
		FileUtils.copyFile(posterShot, screenshotLocation);
		driver.quit();
	

网页在浏览器的样式


这里要说一下代码:

driver.manage().window().setSize(new Dimension(1920,1200));

可以看到后面的注释有

//new Dimension(1024,768)|new Dimension(1440,900)

我发现这两个分辨率即使在截整屏时海报都显示不全,更合况在截取元素时图片也是不全的。在1920x1200时生成的整屏图片的比率为

运行代码后控制的显示如下:

#poster宽和高的值在浏览器浏览是正确的,但看这个整屏的图的大小都能猜到起码的左上角的起始作坐肯定是错的

哪如何知道左上角的起始坐标呢,实际操作可以通过window的画图软件中打开图片都能知道

使用以下的代码都可以截取正确的元素截图

BufferedImage eleScreenshot= fullImg.getSubimage(818, 138, 750, 1072);

这都难堪了,怎么通过程序算出左上角的起始作标?怎么通过程序算出在指定窗口中的实际元素的宽和高?

以上是关于可以使用selenium的WebDriver将指定元素截图吗?的主要内容,如果未能解决你的问题,请参考以下文章

Selenium+Python+Webdriver:保存截图到指定文件夹

我们可以将TestNG与Selenium WebDriver和Cucumber一起使用吗? [关闭]

将 PhantomJS 与 Selenium Webdriver 和 Python 一起使用

如何使用 Selenium Webdriver 模拟特定用户?

利用 Python + Selenium 实现对页面的指定元素截图(可截长图元素)

使用ImageMagick和Selenium Webdriver进行自动化视觉测试