Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 硒铬屏幕截图-html2canvas_Java_Google Chrome_Selenium_Selenium Webdriver_Html2canvas - Fatal编程技术网

Java 硒铬屏幕截图-html2canvas

Java 硒铬屏幕截图-html2canvas,java,google-chrome,selenium,selenium-webdriver,html2canvas,Java,Google Chrome,Selenium,Selenium Webdriver,Html2canvas,我正在使用html2canvas.js库与selenium一起拍摄全页屏幕截图 public class ChromeCanvasCapture { private static final String APP_URL = "http://www.flipkart.com"; public static String getFileContent(String filePath) throws FileNotFoundException, IOExcepti

我正在使用html2canvas.js库与selenium一起拍摄全页屏幕截图

public class ChromeCanvasCapture {

    private static final String APP_URL = "http://www.flipkart.com";

    public static String getFileContent(String filePath)
        throws FileNotFoundException, IOException {
        FileInputStream inputStream = new FileInputStream(filePath);
        String fileContent = IOUtils.toString(inputStream);
        inputStream.close();
        return fileContent;
    }

    public static void main(String[] args) {

        WebDriver webDriver = null;

        try {
            System.setProperty("webdriver.chrome.driver",
                "D:\\Drivers\\chromedriver.exe");
            webDriver = new ChromeDriver();
            webDriver.get(APP_URL);
            webDriver.manage().window().maximize();

            if (webDriver instanceof JavascriptExecutor) {
                // scroll to the bottom of the page
                ((JavascriptExecutor) webDriver)                        .executeScript("window.scrollTo(0,document.body.scrollHeight)");
                // //scroll to the top of the page
                ((JavascriptExecutor) webDriver)
                    .executeScript("window.scrollTo(0,0)");
            }

            String jsFile = getFileContent("html2canvas.js");
            jsFile = jsFile
                + " var webDriverCallback = arguments[arguments.length - 1]; html2canvas(document.body, {onrendered: function(canvas) {var img = canvas.toDataURL('image/png').replace('data:image/png;base64,', '');; webDriverCallback(img); }";
            System.out.println(jsFile);
            webDriver.manage().timeouts().setScriptTimeout(5, TimeUnit.SECONDS);
            if (webDriver instanceof JavascriptExecutor) {
                JavascriptExecutor executor = (JavascriptExecutor) webDriver;
                Object result = executor.executeAsyncScript(jsFile);
                String imageString = String.valueOf(result);
                byte[] imageData = Base64.decodeBase64(imageString);
                OutputStream outputStream = new FileOutputStream(
                    "C:\\Captures\\canvas_captured.png");
                outputStream.write(imageData);
                outputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // webDriver.quit();
        }
    }
}
我将html2canvas.js文件保存在java项目的类路径中。我用来获取屏幕截图的java脚本代码是:

var webDriverCallback = arguments[arguments.length - 1];

html2canvas(document.body, {
    onrendered: function(canvas) {
        var img = canvas.toDataURL('image/png').replace('data:image/png;base64,', '');;
        webDriverCallback(img);
    }
});
我能够捕获flipkart页面的全页屏幕截图,但没有任何图像

我无法从chrome使用TakeScreenshot实用程序,因为它不允许使用chrome浏览器拍摄整页屏幕快照


html2canvas脚本通过遍历页面的DOM来工作,它收集所有元素的信息,然后,它使用它来构建页面的表示,这意味着它实际上不获取页面的屏幕截图,而是通过读取DOM来构建表示(ie)整个图像是在客户端浏览器上创建的,因此它也不会绕过任何浏览器内容策略限制

根据同源策略,web浏览器允许网页中包含的脚本从另一个网页访问数据,前提是两个网页具有相同的源。因此,脚本使用的所有图像都需要位于同一来源下才能读取。但在您的情况下,这些图像是从不同的域加载到flipkart.com中的(您可以通过flipkart中图像的src属性验证这一点)

另一个选择是使用代理,但目前没有针对java的html2canvas。如果您绝对需要,您可以构建一个代理

如果您感兴趣,请选择其他解决方案

伪代码

document.documentElement.scrollHeight //gives total page height

document.documentElement.clientHeight //gives current screen height

//You can write ur logic ex : if scroll height is greater than client height scroll
if(document.documentElement.scrollHeight>document.documentElement.clientHeight)
//take screenshot and then scroll(Do this till the end of the page)
}
最后,将所有屏幕截图合并到一个图像文件中


希望这对您有所帮助…如果您有任何疑问,请返回。您可以使用以下内容。
但您必须处理一些等待,直到加载所有图像。
它可以选择跳过重复的元素,因为flipkart的标题搜索横幅是重复的,所以我将其作为要隐藏的元素传递

    driver.get("http://www.flipkart.com");
    WebDriverWait wait = new WebDriverWait(driver, 60);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[contains(@class,'fk-ui-ccarousel-supercontainer requirecss-HPS')]")));

    WebElement header = driver.findElement(By.id("fk-header"));
    //As header is repeating we are giving it as repetitive element so that it will remove it while taking screenshot
    Files.copy(Utils.makeFullScreenshot(driver, header), new File("D:\\fsile.png"));
Utils.Java
这是GalenFramework的一个修改

导入java.awt.Graphics2D;
导入java.awt.image.buffereImage;
导入java.io.ByteArrayInputStream;
导入java.io.File;
导入java.io.IOException;
导入javax.imageio.imageio;
导入org.openqa.selenium.JavascriptExecutor;
导入org.openqa.selenium.OutputType;
导入org.openqa.selenium.TakesScreenshot;
导入org.openqa.selenium.WebDriver;
导入org.openqa.selenium.WebElement;
公共类UTIL{
私有静态最终字符串JS_RETRIEVE_DEVICE_PIXEL_RATIO=“var pr=window.devicePixelRatio;if(pr!=undefined&&pr!=null)返回pr;else返回1.0;”;
私有静态void hideScroll(WebDriver驱动程序){
((JavascriptExecutor)driver).executeScript(“document.documentElement.style.overflow='hidden';”;
}
私有静态无效显示滚动(WebDriver驱动程序){
((JavascriptExecutor)driver).executeScript(“document.documentElement.style.overflow='visible';”;
}
私有静态void showHideElements(WebDriver驱动程序、布尔隐藏、WebElement…skipElements){
字符串显示;
如果(隐藏){
display=“无”;
}否则{
display=“block”;
}
如果(skipElements!=null){
for(WebElement skipElement:skipElements){
((JavascriptExecutor)driver).executeScript(“参数[0].style.display='”+display+“;”,skipElement);
}
}
}
私有静态字节[]获取屏幕截图(WebDriver驱动程序){
return((TakesScreenshot)driver.getScreenshotAs(OutputType.BYTES);
}
//执行此任务的代码
公共静态文件makeFullScreenshot(WebDriver驱动程序、WebElement…skipElements)引发IOException、InterruptedException{
//滚动到底部以确保所有元素都正确加载
//滚动垂直至(驱动程序,(内部)长滚动高度);
//首先向上滚动开始拍摄屏幕截图
滚动到(驱动程序,0);
hideScroll(司机);
//首次尝试时无需隐藏元素
字节[]字节=getScreenShot(驱动程序);
showHideElements(驾驶员、真实、滑雪装备);
long longScrollHeight=(long)((JavascriptExecutor)驱动程序).executeScript(“返回数学.max(”
+document.body.scrollHeight,document.documentElement.scrollHeight
+document.body.offsetHeight,document.documentElement.offsetHeight
+document.body.clientHeight,document.documentElement.clientHeight)
);
BuffereImage image=ImageIO.read(新的ByteArrayInputStream(字节));
int capturedWidth=image.getWidth();
int capturedHeight=image.getHeight();
Double devicePixelRatio=((数字)((JavascriptExecutor)驱动程序).executeScript(JS_检索_设备_像素_比率)).doubleValue();
int scrollHeight=(int)longScrollHeight;
File File=File.createTempFile(“屏幕截图”、“.png”);
int adapted capturedHeight=(int)((双)capturedHeight)/devicePixelRatio;
缓冲图像结果图像;
if(数学abs(自适应CapturedHeight-滚动高度)>40){
int scrollOffset=适配CapturedHeight;
整数倍=滚动高度/自适应捕获高度;
int leftover=滚动高度%adaptedCapturedHeight;
最终BuffereImage TileImage=新的BuffereImage(capturedWidth,(int)((双)滚动高度)*设备像素比率),BuffereImage.TYPE_int_RGB);
Graphics2D g2dTile=tileImage.createGraphics();
g2dTile.drawImage(image,0,0,null);
int-scroll=0;
对于(int i=0;i<乘以-1;i++){
滚动+=滚动偏移量;
scrollVerticallyTo(驱动程序,滚动);
BuffereImage nextImage=ImageIO.read(新的ByteArrayInputStream(获取屏幕截图(驱动程序));
g2dTile.drawImage(下一个图像,0,(i+1)*capturedHeight,null);
}
如果(剩余>0){
滚动+=滚动偏移量;
scrollVerticallyTo(驱动程序,滚动);
BuffereImage nextImage=ImageIO.read(新的ByteArrayInputStream(获取屏幕截图(驱动程序));
日分
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class Utils {

private static final String JS_RETRIEVE_DEVICE_PIXEL_RATIO = "var pr = window.devicePixelRatio; if (pr != undefined && pr != null)return pr; else return 1.0;";

private static void hideScroll(WebDriver driver) {
    ((JavascriptExecutor) driver).executeScript("document.documentElement.style.overflow = 'hidden';");
}

private static void showScroll(WebDriver driver) {
    ((JavascriptExecutor) driver).executeScript("document.documentElement.style.overflow = 'visible';");
}

private static void showHideElements(WebDriver driver, Boolean hide, WebElement... skipElements) {
    String display;
    if (hide) {
        display = "none";
    } else {
        display = "block";
    }
    if (skipElements != null) {
        for (WebElement skipElement : skipElements) {
            ((JavascriptExecutor) driver).executeScript("arguments[0].style.display = '" + display + "';", skipElement);
        }
    }
}

private static byte[] getScreenShot(WebDriver driver) {
    return ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
}

//The code that does the job
public static File makeFullScreenshot(WebDriver driver, WebElement... skipElements) throws IOException, InterruptedException {
    //Scroll to bottom to make sure all elements loaded correctly
    // scrollVerticallyTo(driver, (int) longScrollHeight);

    // scroll up first to start taking screenshots
    scrollVerticallyTo(driver, 0);
    hideScroll(driver);
    //No need to hide elements for first attempt
    byte[] bytes = getScreenShot(driver);

    showHideElements(driver, true, skipElements);
    long longScrollHeight = (Long) ((JavascriptExecutor) driver).executeScript("return Math.max("
            + "document.body.scrollHeight, document.documentElement.scrollHeight,"
            + "document.body.offsetHeight, document.documentElement.offsetHeight,"
            + "document.body.clientHeight, document.documentElement.clientHeight);"
    );

    BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes));
    int capturedWidth = image.getWidth();
    int capturedHeight = image.getHeight();

    Double devicePixelRatio = ((Number) ((JavascriptExecutor) driver).executeScript(JS_RETRIEVE_DEVICE_PIXEL_RATIO)).doubleValue();

    int scrollHeight = (int) longScrollHeight;

    File file = File.createTempFile("screenshot", ".png");

    int adaptedCapturedHeight = (int) (((double) capturedHeight) / devicePixelRatio);

    BufferedImage resultingImage;

    if (Math.abs(adaptedCapturedHeight - scrollHeight) > 40) {
        int scrollOffset = adaptedCapturedHeight;

        int times = scrollHeight / adaptedCapturedHeight;
        int leftover = scrollHeight % adaptedCapturedHeight;

        final BufferedImage tiledImage = new BufferedImage(capturedWidth, (int) (((double) scrollHeight) * devicePixelRatio), BufferedImage.TYPE_INT_RGB);
        Graphics2D g2dTile = tiledImage.createGraphics();
        g2dTile.drawImage(image, 0, 0, null);

        int scroll = 0;
        for (int i = 0; i < times - 1; i++) {
            scroll += scrollOffset;
            scrollVerticallyTo(driver, scroll);
            BufferedImage nextImage = ImageIO.read(new ByteArrayInputStream(getScreenShot(driver)));
            g2dTile.drawImage(nextImage, 0, (i + 1) * capturedHeight, null);
        }
        if (leftover > 0) {
            scroll += scrollOffset;
            scrollVerticallyTo(driver, scroll);
            BufferedImage nextImage = ImageIO.read(new ByteArrayInputStream(getScreenShot(driver)));
            BufferedImage lastPart = nextImage.getSubimage(0, nextImage.getHeight() - (int) (((double) leftover) * devicePixelRatio), nextImage.getWidth(), leftover);
            g2dTile.drawImage(lastPart, 0, times * capturedHeight, null);
        }

        scrollVerticallyTo(driver, 0);

        resultingImage = tiledImage;
    } else {
        resultingImage = image;
    }
    showScroll(driver);
    showHideElements(driver, false, skipElements);
    ImageIO.write(resultingImage, "png", file);
    return file;
}

private static void scrollVerticallyTo(WebDriver driver, int scroll) {
    ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, " + scroll + ");");
    try {
        waitUntilItIsScrolledToPosition(driver, scroll);
    } catch (InterruptedException e) {
       // LOG.trace("Interrupt error during scrolling occurred.", e);
    }
}

private static void waitUntilItIsScrolledToPosition(WebDriver driver, int scrollPosition) throws InterruptedException {
    int hardTime = 0;//SCREENSHOT_FULLPAGE_SCROLLWAIT
    if (hardTime > 0) {
        Thread.sleep(hardTime);
    }
    int time = 250;//SCREENSHOT_FULLPAGE_SCROLLTIMEOUT
    boolean isScrolledToPosition = false;
    while (time >= 0 && !isScrolledToPosition) {
        Thread.sleep(50);
        time -= 50;
        isScrolledToPosition = Math.abs(obtainVerticalScrollPosition(driver) - scrollPosition) < 3;
    }
}

private static int obtainVerticalScrollPosition(WebDriver driver) {
    Long scrollLong = (Long) ((JavascriptExecutor) driver).executeScript("return (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;");
    return scrollLong.intValue();
}
}