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

13 篇文章 0 订阅
8 篇文章 0 订阅

项目有个小功能:为指定文章生成一份分享海报,看到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包
selenium-firefox-driver依赖的插件

写个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);

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值