我遇到了:
Exception in thread "main" java.lang.NullPointerException at org.openqa.selenium.remote.RemoteWebElement.getLocation(RemoteWebElement.java:338)
尝试在https://signup.live.com/获取验证码的BufferedImage:
public BufferedImage getCaptchaBufferedImage() throws IOException, InterruptedException {
System.out.println("Looking for captcha image");
this.wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("hipTemplateContainer")));
System.out.println("Found image");
WebElement element = this.driver.findElement(By.id("hipTemplateContainer"));
System.out.println(element.getAttribute("outerHTML"));
List<WebElement> childs = element.findElements(By.xpath(".//*"));
WebElement firstChild = childs.get(0);
System.out.println(firstChild.getAttribute("outerHTML"));
List<WebElement> childs2 = firstChild.findElements(By.xpath(".//*"));
WebElement imageChild = childs2.get(0);
System.out.println(imageChild.getAttribute("outerHTML"));
((JavascriptExecutor) this.driver).executeScript("arguments[0].scrollIntoView(true);", imageChild);
String id = imageChild.getAttribute("id");
this.wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(id)));
**Point point = firstChild.getLocation();**
byte[] img_bytes = ((TakesScreenshot) this.driver).getScreenshotAs(OutputType.BYTES);
BufferedImage imageScreen = ImageIO.read(new ByteArrayInputStream(img_bytes));
System.out.println("Downloaded image");
double d = Double.parseDouble(firstChild.getCssValue("height").split("px")[0]);
int height = (int) d;
double e = Double.parseDouble(firstChild.getCssValue("width").split("px")[0]);
int width = (int) e;
BufferedImage captcha = imageScreen.getSubimage(point.getX(), point.getY(), width, height);
JFrame frame = new JFrame();
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(new JLabel(new ImageIcon(captcha)));
frame.pack();
frame.setVisible(true);
return captcha;
}
我在网上看了一遍,无法解决这个问题.Selenium 3.0可能存在错误?如果我跳过获取图像的偏移量并且只是对getSubImage()中的值进行硬编码,则此代码有效。
答案 0 :(得分:1)
我试了两个多小时才猜到了什么?我发现了这个问题。
<强>问题:强>
这是因为getScreenshotAs
仅占用页面的可见部分(在滚动到验证码之后)但没有完成页面,因此导致所有问题。它导致Point返回的Y坐标(1041
)相对于complete
网页,但截图图像具有不同的Y坐标,用于验证码(300
)相对到部分页面。因此导致以下例外:
java.awt.image.RasterFormatException: (y + height) is outside of Raster
X坐标在完整网页和部分中都是相同的值 网页。
所以,将Y坐标硬编码为300解决了临时问题。 BUt实际问题是为什么没有为完整页面而不是jus可见页面截取屏幕截图。可能是最新的geckodriver(firefox驱动程序)中的错误。在Firefox 49 version with Selenium 3 version, geckodriver v0.1.11 and Java 1.8
尝试过。
以下是代码。请尝试告诉我:
driver.get("https://signup.live.com/");
driver.manage().window().maximize();
System.out.println("Looking for captcha image");
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("hipTemplateContainer")));
System.out.println("Found image");
WebElement element = driver.findElement(By.id("hipTemplateContainer"));
System.out.println(element.getAttribute("outerHTML"));
List<WebElement> childs = element.findElements(By.xpath(".//*"));
WebElement firstChild = childs.get(0);
System.out.println(firstChild.getAttribute("outerHTML"));
List<WebElement> childs2 = firstChild.findElements(By.xpath(".//*"));
WebElement imageChild = childs2.get(0);
System.out.println(imageChild.getAttribute("outerHTML"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", imageChild);
String id = imageChild.getAttribute("id");
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(id)));
Point point = imageChild.getLocation();
int width = imageChild.getSize().getWidth();
int height = imageChild.getSize().getHeight();
System.out.println("height: " + height + "\t weight : " + width);
System.out.println("X co-ordinate: " + point.getX());
System.out.println("Y co-ordinate: " + point.getY());
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenshot, new File("G:\\naveen\\screenshot.png"));
BufferedImage imageScreen = ImageIO.read(screenshot);
System.out.println("Downloaded image");
BufferedImage captcha = imageScreen.getSubimage(245, 300, width, height);
ImageIO.write(captcha, "png", screenshot);
FileUtils.copyFile(screenshot, new File("G:\\naveen\\screenshot1.png"));
JFrame frame = new JFrame();
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(new JLabel(new ImageIcon(captcha)));
frame.pack();
frame.setVisible(true);
以下是保存的屏幕截图: