我有一个来自this教程的代码。它进入了learning-selenium-easy.blogspot.com网站,在“阅读次数最多/受欢迎的帖子”部分中查找并拍照:
class SshotofElement {
public static void screenShotElement() throws InterruptedException,IOException {
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability("marionette", true);
WebDriver driver = new ChromeDriver(capabilities);
driver.get("http://learn-selenium-easy.blogspot.com/");
driver.manage().window().maximize();
// Xpath of element to take screen shot
WebElement element=driver.findElement(By.xpath("//*[@id='PopularPosts1']"));
System.out.println(element.getSize());
File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Take full screen screenshot
BufferedImage fullImg = ImageIO.read(screenshot);
Point point = element.getLocation();
int elementWidth = element.getSize().getWidth();
int elementHeight = element.getSize().getHeight();
BufferedImage elementScreenshot= fullImg.getSubimage(point.getX(), point.getY(), elementWidth,elementHeight); //exception here
// crop the image to required
ImageIO.write(elementScreenshot, "png", screenshot);
FileUtils.copyFile(screenshot, new File("mostread_screenshot.png"));//path to save screen shot
driver.close();
}
}
我遇到java.awt.image.RasterFormatException: (y + height) is outside of Raster
异常,但是在第BufferedImage elementScreenshot= fullImg.getSubimage(point.getX(), point.getY(), elementWidth,elementHeight);
行。我不确定为什么会这样,因为图像的点和大小是从元素本身获取的。
答案 0 :(得分:1)
您正在裁剪的元素图像在代码拍摄的屏幕快照中不存在。如果您放置调试并打印全屏快照路径并手动查看,则可以看到其中没有从图像中裁剪出所需的元素。
因此,首先我们需要滚动页面,将所需元素带入视图,然后截取屏幕截图。然后我们需要根据元素的位置裁剪图像。
此外,Point
类也不十分可靠,无法提供元素的确切位置。
第二,如果我们看到以下值
ImageIO.read(screenshot).getHeight() // ~ 943 => Total height
element.getSize().getHeight() // ~ 511 => Element height
point.getY() // ~ 743 => start top side y coordinate of element
所以我相信从x,y绘制高度为743的矩形时 超出了原始屏幕截图坐标。
所以我们需要在传递坐标的同时进行一些调整。
@Test
public void subImageTest() throws InterruptedException, IOException {
driver.get("http://learn-selenium-easy.blogspot.com/");
((JavascriptExecutor)driver).executeScript("window.scrollBy(0,600)");
File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
WebElement element=driver.findElement(By.xpath("//*[@id='PopularPosts1']"));
System.out.println(element.getSize());
// Take full screen screenshot
BufferedImage fullImg = ImageIO.read(screenshot);
ImageIO.read(screenshot).getHeight()
System.out.println(fullImg.getHeight());
System.out.println(fullImg.getWidth());
Point point = element.getLocation();
int elementWidth = element.getSize().getWidth();
int elementHeight = element.getSize().getHeight();
// Now no exception here
BufferedImage elementScreenshot= fullImg.getSubimage(220, 170,elementWidth+150,elementHeight+100);
// crop the image to required
ImageIO.write(elementScreenshot, "png", screenshot);
FileUtils.copyFile(screenshot, new File("C:\\Users\\AppData\\Local\\Temp\\mostread_screenshot.png"));//path to save screen shot
}
答案 1 :(得分:1)
如果<{3}}中的布局信息无效,则会抛出
根据硒文档 Raster返回包含该元素左上角位置的点。
根据 Java文档 getLocation()
返回由指定矩形区域定义的子图像。返回的BufferedImage与原始图像共享相同的数据数组,并定义为:
getSubimage
public BufferedImage getSubimage(int x,
int y,
int w,
int h)
Returns a subimage defined by a specified rectangular region. The returned BufferedImage shares the same data array as the original image.
Parameters:
x - the X coordinate of the upper-left corner of the specified rectangular region
y - the Y coordinate of the upper-left corner of the specified rectangular region
w - the width of the specified rectangular region
h - the height of the specified rectangular region
Returns:
a BufferedImage that is the subimage of this BufferedImage.
Throws:
RasterFormatException - if the specified area is not contained within this BufferedImage.
我已经编写了自己的代码,并添加了几行System.out.println()
以展示到底出了什么问题。
代码块:
public class A_demo
{
public static void main(String[] args) throws Exception
{
System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments("start-maximized");
options.addArguments("disable-infobars");
WebDriver driver = new ChromeDriver(options);
driver.get("http://learn-selenium-easy.blogspot.com/");
// Xpath of element to take screen shot
WebElement element=driver.findElement(By.xpath("//*[@id='PopularPosts1']"));
System.out.println("Element size is:"+element.getSize());
File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File("./Screenshots/mostread_TakesScreenshot.png")); //path to save screen shot
// Take full screen screenshot
BufferedImage fullImg = ImageIO.read(screenshot);
Point point = element.getLocation();
System.out.println("Co-ordinates where on the page is the top left-hand corner of the rendered element:"+point);
int elementWidth = element.getSize().getWidth();
System.out.println("Element width is:"+elementWidth);
int elementHeight = element.getSize().getHeight();
System.out.println("Element height is:"+elementHeight);
BufferedImage elementScreenshot= fullImg.getSubimage(point.getX(), point.getY(), elementWidth,elementHeight); //exception here
// crop the image to required
ImageIO.write(elementScreenshot, "png", screenshot);
FileUtils.copyFile(screenshot, new File("./Screenshots/mostread_BufferedImage.png"));//path to save screen shot
}
}
控制台输出:
INFO: Detected dialect: W3C
Element size is:(340, 486)
Co-ordinates where on the page is the top left-hand corner of the rendered element:(104, 744)
Element width is:340
Element height is:486
Exception in thread "main" java.awt.image.RasterFormatException: (y + height) is outside of Raster
at sun.awt.image.ByteInterleavedRaster.createWritableChild(Unknown Source)
at java.awt.image.BufferedImage.getSubimage(Unknown Source)
at demo.A_demo.main(A_demo.java:78)
如前所述,按照您的代码块fullImg.getSubimage()
将尝试返回BufferedImage
,即 elementScreenshot ,它将是由矩形区域指定的子图像:
point.getX()
- 104 point.getY()
- 744 因此,BufferedImage
的预期高度变为744
+ 486
= 1230
,这与光栅。因此,您会看到错误。
要使用getSubimage()
和selenium截取特定元素或特定div的屏幕截图,可以使用 AShot()
方法导入 ashot- Selenium Java Client v3.14.0 , ChromeDriver v2.41 , Chrome v 68.0 时为1.4.4.jar 。 / p>
注意: ashot-1.4.4.jar 中的
AShot()
方法仅在启用java的情况下有效< em> Web应用程序。
代码块:
import ru.yandex.qatools.ashot.AShot;
import ru.yandex.qatools.ashot.Screenshot;
public class A_demo
{
public static void main(String[] args) throws Exception
{
System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments("start-maximized");
options.addArguments("disable-infobars");
WebDriver driver = new ChromeDriver(options);
driver.get("http://learn-selenium-easy.blogspot.com/");
WebElement myWebElement = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='PopularPosts1']")));
((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView();", myWebElement);
Screenshot myScreenshot = new AShot().takeScreenshot(driver, myWebElement);
ImageIO.write(myScreenshot.getImage(),"PNG",new File("./Screenshots/elementAShotScreenshot.png"));
driver.quit();
}
}
您可以在以下位置找到一些相关的讨论
您可以在Selenium: Not able to take complete page screenshot using aShot library
中找到有关所有基于 Java 的屏幕截图方法的详细讨论。