我切换到Firefox,以下代码对我有效。但是目前它不起作用,因为selenium与我的Firefox版本47不兼容,请参见https://github.com/SeleniumHQ/selenium/issues/2257。所以我现在无法测试这段代码,但上次我能够使用它获取视网膜截图:
package de.kicktipp.screenshots.stackoverflow;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
public class ScreenshotMaker
{
private PhoneList phoneList = new PhoneList();
private static final String HOST = "https://m.kicktipp.de";
private static final String PATH = "/";
private File resultDirectory;
private int filenumber = 0;
public static void main ( String[] args ) throws Exception
{
ScreenshotMaker screenshotMaker = new ScreenshotMaker();
screenshotMaker.run();
}
public WebDriver getDriver ( Phone phone, Display display )
{
FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("reader.parse-on-load.enabled", false);
profile.setPreference("xpinstall.signatures.required", false);
FirefoxBinary firefoxBinary = new FirefoxBinary();
firefoxBinary.setEnvironmentProperty("DISPLAY", display.getDisplayNumberString());
FirefoxDriver firefoxDriver = new FirefoxDriver(firefoxBinary, profile);
firefoxDriver.manage().window().setSize(new Dimension(phone.getWidth(), display.getHeight()));
return firefoxDriver;
}
private void run ( ) throws Exception
{
mkdir();
for (Phone phone : phoneList)
{
WebDriver driver = null;
Display display = null;
try
{
display = new Display(phone.getDpiFaktor());
driver = getDriver(phone, display);
System.out.println(phone.getName());
filenumber = 0;
System.out.println("");
System.out.println("Generating Screenshots for " + phone.getName());
System.out.println("-----------------------------------------------------------------------------");
driver.get(HOST + "/");
shot(display, driver, PATH, phone);
}
finally
{
if (driver != null)
{
driver.quit();
}
if (display != null)
{
display.shutdown();
}
}
}
System.out.println("");
System.out.println("-----------------------------------------------------------------------------");
System.out.println("Finished.");
}
private void mkdir ( ) throws IOException
{
File targetDir = targetDir();
resultDirectory = new File(targetDir, "results");
resultDirectory.mkdir();
System.out.println("Writing screenshots to " + resultDirectory.getCanonicalPath());
}
public File targetDir ( )
{
String relPath = getClass().getProtectionDomain().getCodeSource().getLocation().getFile();
File targetDir = new File(relPath + "../..");
if (!targetDir.exists())
{
targetDir.mkdir();
}
return targetDir;
}
private void shot ( Display display, WebDriver driver, String path, Phone phoneSpec ) throws Exception
{
String url = getUrl(path);
driver.get(url);
scrollToRemoveScrollbars(driver);
File srcFile = display.captureScreenshot();
moveFile(srcFile, phoneSpec);
}
private void scrollToRemoveScrollbars ( WebDriver driver ) throws Exception
{
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollTo(0,20);");
js.executeScript("window.scrollTo(0,0);");
Thread.sleep(800);
}
private String getUrl ( String path )
{
StringBuffer url = new StringBuffer(HOST);
url.append(path);
return url.toString();
}
private void moveFile ( File srcFile, Phone phone ) throws Exception
{
String filename = phone.getFilename(filenumber);
File file = new File(resultDirectory, filename);
if (file.exists())
{
file.delete();
}
crop(srcFile, file, phone);
System.out.println(filename);
}
private void crop ( File srcFile, File targetFile, Phone phone ) throws Exception
{
int width = phone.getPixelWidth();
int height = phone.getPixelHeight();
int yStart = 71 * phone.getDpiFaktor();
Image orig = ImageIO.read(srcFile);
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
bi.getGraphics().drawImage(orig, 0, 0, width, height, 0, yStart, width, height + yStart, null);
ImageIO.write(bi, "png", targetFile);
}
}
class PhoneList extends ArrayList<Phone>
{
private static final Phone IPHONE_4 = new Phone(320, 460, "iphone4", 2);
private static final Phone IPHONE_5 = new Phone(320, 548, "iphone5", 2);
private static final Phone IPHONE_6 = new Phone(375, 667, "iphone6", 2);
private static final Phone IPAD = new Phone(1024, 748, "ipad", 2);
private static final Phone IPHONE_6_PLUS = new Phone(414, 736, "iphone6plus", 3);
private static final Phone AMAZON = new Phone(480, 800, "amazon", 1);
public PhoneList ()
{
add(AMAZON);
add(IPHONE_4);
add(IPHONE_5);
add(IPHONE_6);
add(IPAD);
add(IPHONE_6_PLUS);
}
}
class Phone
{
private int width = 0;
private int height = 0;
private String name = "";
private int dpiFaktor = 2;
public Phone ( int width, int height, String name, int dpiFaktor )
{
this.width = width;
this.height = height;
this.name = name;
this.dpiFaktor = dpiFaktor;
}
public int getWidth ( )
{
return width;
}
public int getHeight ( )
{
return height;
}
public int getPixelWidth ( )
{
return width * dpiFaktor;
}
public int getPixelHeight ( )
{
return height * dpiFaktor;
}
public int getDpiFaktor ( )
{
return dpiFaktor;
}
public String getName ( )
{
return name;
}
public Dimension getDimension ( )
{
return new Dimension(width, height);
}
public String getFilename ( int number )
{
String dimension = getPixelWidth() + "x" + getPixelHeight();
return name + "-" + dimension + "-" + number + ".png";
}
}
class Display
{
private static final int HEIGHT = 5000;
private static final int WIDTH = 5000;
private static String XVFB = "/usr/bin/Xvfb";
private static String DISPLAY_NUMBER_STRING = ":99";
private static String SCREEN_SIZE = " -screen 0 " + WIDTH + "x" + HEIGHT + "x24";
private static String XVFB_COMMAND = XVFB + " " + DISPLAY_NUMBER_STRING + SCREEN_SIZE + " -dpi ";
private static int baseDpi = 100;
private Process p;
public Display ( int dpiFaktor ) throws IOException, InterruptedException
{
checkExecutable();
int dpi = baseDpi * dpiFaktor;
String cmd = XVFB_COMMAND + dpi;
p = Runtime.getRuntime().exec(cmd);
Thread.sleep(1000);
try
{
int exitValue = p.exitValue();
String msgTemplate = "ERROR: Exit Value: %s. Display konnte nicht gestartet werden. Läuft ein Display noch auf %s ?";
String msg = String.format(msgTemplate, exitValue, DISPLAY_NUMBER_STRING);
throw new IllegalStateException(msg);
}
catch (IllegalThreadStateException e)
{
System.out.println("Switched on display at " + dpi + "dpi with command " + cmd);
return;
}
}
private void checkExecutable ( )
{
File file = new File(XVFB);
if (!file.canExecute())
{
System.err.println("Xvfb is not installed at " + XVFB);
System.err.println("Install Xvfb by runing");
System.err.println("apt-get install xvfb");
}
}
public File captureScreenshot ( ) throws IOException, InterruptedException
{
File tempFile = File.createTempFile("screenshots", ".png");
String absolutePath = tempFile.getAbsolutePath();
String cmd = "import -window root " + absolutePath;
String[] env = new String[] { "DISPLAY=" + DISPLAY_NUMBER_STRING };
Process exec = Runtime.getRuntime().exec(cmd, env);
exec.waitFor();
return tempFile;
}
public void shutdown ( ) throws IOException, InterruptedException
{
p.destroy();
try
{
Thread.sleep(1000);
int exitValue = p.exitValue();
System.out.println("Display was switched off. ExitValue: " + exitValue);
}
catch (IllegalThreadStateException e)
{
p = Runtime.getRuntime().exec("pkill Xvfb");
}
}
public String getDisplayNumberString ( )
{
return DISPLAY_NUMBER_STRING;
}
public int getHeight ( )
{
return HEIGHT;
}
}
这是我的pom文件:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.kicktipp</groupId>
<artifactId>screenshots</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>screenshots</name>
<properties>
<jdk.version>1.7</jdk.version>
<maven.version>3.0</maven.version>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<selenium-java.version>2.53.1</selenium-java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium-java.version}</version>
</dependency>
</dependencies>
</project>