如何使用Selenium WebDriver获取整个网页的截图(整页截图),而不仅仅是部分(从上到下)?
我的代码:( Java绑定)
System.setProperty("webdriver.chrome.driver","/home/alex/Downloads/chromedriver_linux64/chromedriver");
WebDriver driver = new ChromeDriver();
driver.get("http://google.com");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File(RESULT_FILENAME));
关于如何解决这个问题的任何想法?
答案 0 :(得分:13)
LE:我看到很多人对整页截图感兴趣,所以我想我可能会用一些积极的方式更新答案(银子弹)
有相当多的网络测试框架可以(以最少的设置和努力)生成 整页截图 。我来自NodeJS测试环境,所以我只能保证以下内容:WebdriverIO&谷歌的Puppeteer。
如果有人对使用WebdriverIO的简单方法感兴趣,请检查this answer。
简短回答是否,你不能,如果你只使用Selenium (详细原因如下)。但是,您可以做的是充分利用您的设备(监视器)viewport。
因此,使用ChromeOptions()
启动浏览器实例(驱动程序),这是设置ChromeDriver特定功能的方法。我们可以做到以下几点:
--start-maximized
开关); F11
开关在Windows上全屏显示(Control+Cmd+F
- 键,在Mac上使用--start-fullscreen
。 您的代码应如下所示:
// Setting your Chrome options (Desired capabilities)
ChromeOptions options = new ChromeOptions();
options.add_argument('--start-maximized');
options.add_argument('--start-fullscreen');
// Creating a driver instance with the previous capabilities
WebDriver driver = new ChromeDriver(options);
// Load page & take screenshot of full-screen page
driver.get("http://google.com");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
现在关于整页问题,所有驱动程序(chromedriver
,geckodriver
,IEDriver
,EdgeDriver
等)都在实施WebDriver W3C标准。因此,它们依赖于WebDriver团队希望公开不同功能的功能的方式,在我们的例子中,'Take Screenshot'。
如果你阅读了这个定义,它会清楚地说明以下内容:
Take Screenshot命令获取顶级浏览上下文 VIEWPORT 的屏幕截图。
传统方面,一些驱动程序能够生成整页截图(阅读更多关于它here),就像旧的FirefoxDriver,IEDriver等一样。现在不再是这样了,因为他们现在都在实施(致信)WebDriver W3C标准。
答案 1 :(得分:5)
我找到了一个教程http://www.softwaretestingmaterial.com/how-to-capture-full-page-screenshot-using-selenium-webdriver/ 对于maven用户:请记住从https://mvnrepository.com/artifact/ru.yandex.qatools.ashot/ashot添加依赖关系 当我测试这个脚本时,我有大图片,这些图片无法在浏览器中打开(太大或破损)。
所以也许有人知道任何脚本,它将页面集中在上次使用的定位器上?
答案 2 :(得分:2)
像这样的article暗示AShot对我有用。另外,我使用以下代码成功将整个屏幕截图嵌入了Cucumber报告中
scenario.embed(takeScreenShotAsByte(getWebDriver()), "image/png");
private static byte[] takeScreenShotAsByte(WebDriver webDriver) throws IOException {
return takeFullPageScreenShotAsByte(webDriver);
}
private static byte[] takeFullPageScreenShotAsByte(WebDriver webDriver) throws IOException {
Screenshot fpScreenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(1000))
.takeScreenshot(webDriver);
BufferedImage originalImage = fpScreenshot.getImage();
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ImageIO.write(originalImage, "png", baos);
baos.flush();
return baos.toByteArray();
}
}
答案 3 :(得分:2)
可以以无头模式启动Chrome,然后将窗口大小设置为与页面正文相同的高度。
由于无头浏览器的高度不取决于显示器的大小,因此您可以使用此无头模式来获取在Chrome浏览器中呈现的完整屏幕截图。
Headless Chrome run with selenium的最高答案似乎显示了使用Java在无头模式下启动Chrome的正确方法。我使用python绑定,但是答案看起来与我的操作非常相似。
这是相关部分。在启动ChromeDriver实例之前,应该先执行此代码。
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("--headless");
ChromeDriver driver = new ChromeDriver(chromeOptions);
如果在无头浏览器中运行chrome不可行,则必须使用Firefox或IE。这两种浏览器都会为您提供完整的屏幕截图
答案 4 :(得分:1)
对于某些页面,我需要截取页面的开头和结尾的截图。所以我用2个截图:
public static String javaIoTmpDir = System.getProperty("java.io.tmpdir"); //tmp dir
//create screenshot
driver.manage().window().fullscreen();
//For large pages - body over 850 px highh - take addition screenshot of the end of page
if (driver.findElements(By.id("panel_body")).size()>0) {
WebElement body = driver.findElement(By.id("panel_body"));
int bodyHight = body.getSize().getHeight();
if (bodyHight > 850) {
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_END);
robot.keyRelease(KeyEvent.VK_END);
Thread.sleep(1000);
File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
String timePictureEnd = javaIoTmpDir+"\\scr_"+String.valueOf(System.currentTimeMillis())+getClass().toString().substring(getClass().toString().lastIndexOf(".qa.")+3)+".png";
FileUtils.copyFile(scrFile, new File(timePictureEnd));
robot.keyPress(KeyEvent.VK_HOME); //back to top page for next screen
robot.keyRelease(KeyEvent.VK_HOME);
Thread.sleep(1000);
}
}
String timePicture = javaIoTmpDir+"\\scr_"+String.valueOf(System.currentTimeMillis())+getClass().toString().substring(getClass().toString().lastIndexOf(".qa.")+3)+".png";
File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File(timePicture));
答案 5 :(得分:1)
您可以使用Phantomjs来实现。
这是我的Java代码:
public class PhantomjsTest {
public static void main(String[] args) {
try {
long start=System.currentTimeMillis();
//The page you want to screenshot
String targetUrl="https://www.iqiyi.com/";
//File path
String targetImg="iqiyi.png";
String command = "/Users/hetiantian/SoftWares/phantomjs/bin/phantomjs /Users/hetiantian/SoftWares/phantomjs/examples/rasterize.js "+targetUrl + " " +targetImg;
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
System.out.println((System.currentTimeMillis()-start));
} catch (Exception e) {
e.printStackTrace();
}
}
}
因此,您可以获取Phantomjs的完整网页的屏幕截图。使用Phantomjs获取完整的屏幕截图时,您需要先下载Phantomjs。然后运行Phantomjs脚本截图。关于它的更多信息,您可以参考phantomjs.org。
答案 6 :(得分:1)
现在有一种使用 Selenium 4 和 Firefox 的简单方法。
byte[] imageBytes = ((FirefoxDriver)driver).getFullPageScreenshotAs(OutputType.BYTES);
Files.write(Paths.get(RESULT_FILENAME), imageBytes);
其他浏览器尚不支持 getFullPageScreenshotAs()
。
答案 7 :(得分:0)
这是我使用C#获取全屏ScreenShot的示例,但只需更改:
string _currentPath = Path.GetDirectoryName(Assembly.GetAssembly(typeof(One of your objects)).Location) + @"\Attachs\";
var filePath = _currentPath + sSName;
if (!Directory.Exists(_currentPath))
Directory.CreateDirectory(_currentPath);
Dictionary<string, Object> metrics = new Dictionary<string, Object>();
metrics["width"] = _driver.ExecuteScript("return Math.max(window.innerWidth,document.body.scrollWidth,document.documentElement.scrollWidth)");
metrics["height"] = _driver.ExecuteScript("return Math.max(window.innerHeight,document.body.scrollHeight,document.documentElement.scrollHeight)");
metrics["deviceScaleFactor"] = (double)_driver.ExecuteScript("return window.devicePixelRatio");
metrics["mobile"] = _driver.ExecuteScript("return typeof window.orientation !== 'undefined'");
_driver.ExecuteChromeCommand("Emulation.setDeviceMetricsOverride", metrics);
_driver.GetScreenshot().SaveAsFile(filePath, ScreenshotImageFormat.Png);
_driver.ExecuteChromeCommand("Emulation.clearDeviceMetricsOverride", new Dictionary<string, Object>());
_driver.Close();
答案 8 :(得分:0)
不使用第三方库的Java代码:
int bodyHeight = webDriver.findElement(By.tagName("body")).getSize().getHeight();
int windowChromeHeight = (int) (long) webDriver.executeScript("return window.outerHeight - window.innerHeight");
Dimension size = new Dimension(webDriver.manage().window().getSize().getWidth(), bodyHeight + windowChromeHeight);
webDriver.executeScript("window.scrollTo(0, 0);");
webDriver.manage().window().setSize(size);
File screenshotFile = new File("screenshot.png");
Files.write(screenshotFile.toPath(), webDriver.getScreenshotAs(OutputType.BYTES));
答案 9 :(得分:-7)
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File("c:\\RESULT_FILENAME.png"));
试试这个