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

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

引入maven依赖

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

最终会下载以下jar包
可以使用selenium的WebDriver将指定元素截图吗?_第1张图片

写个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.

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

可以使用selenium的WebDriver将指定元素截图吗?_第2张图片
卡在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();
	}

网页在浏览器的样式

可以使用selenium的WebDriver将指定元素截图吗?_第3张图片
这里要说一下代码:

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

可以看到后面的注释有

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

我发现这两个分辨率即使在截整屏时海报都显示不全,更合况在截取元素时图片也是不全的。在1920x1200时生成的整屏图片的比率为
可以使用selenium的WebDriver将指定元素截图吗?_第4张图片
运行代码后控制的显示如下:
可以使用selenium的WebDriver将指定元素截图吗?_第5张图片
#poster宽和高的值在浏览器浏览是正确的,但看这个整屏的图的大小都能猜到起码的左上角的起始作坐肯定是错的
可以使用selenium的WebDriver将指定元素截图吗?_第6张图片
哪如何知道左上角的起始坐标呢,实际操作可以通过window的画图软件中打开图片都能知道
可以使用selenium的WebDriver将指定元素截图吗?_第7张图片
使用以下的代码都可以截取正确的元素截图

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

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

你可能感兴趣的:(java,web,eclipse)