PhantomJS,chrome,firefox 驱动截取图片

2021-12-13 10:49:47 浏览数 (1)

代码语言:javascript复制
package com.lenovo.sciv4.utils;


import com.amazonaws.services.s3.model.ObjectMetadata;
import com.itextpdf.text.Rectangle;
import com.lenovo.sciv4.commons.download.utils.S3Connection;
import com.lenovo.sciv4.commons.frameworks.utils.LogUtil;
import com.lenovo.sciv4.entity.SeleniumAccountInfo;
import com.lenovo.sciv4.entity.SeleniumWConfInfo;
import com.lenovo.sciv4.mapper.AccountInfoMapper;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 网页截图
 */
@Component
public class WebPageScreenShot {



    @Autowired
    AccountInfoMapper accountInfoMapper;

    public WebDriver initWebDriver() {
        String chromeDriver = getYmlPath(driverPath);
        System.setProperty("webdriver.chrome.driver", chromeDriver);//chromedriver服务地址
        LogUtil.log("WebDriver 开始加载--------------"   chromeDriver);
        System.setProperty("webdriver.chrome.silentOutput", "true");
        //实例化一个Chrome浏览器的实例
        ChromeOptions options = new ChromeOptions();
        // 字符编码 utf-8 支持中文字符
        options.addArguments("lang=zh_CN.UTF-8");
        options.addArguments("--silent");
        // 开启最大化
        options.addArguments("–start-maximized");
        options.addArguments("–no-sandbox");
        // 开启无头模式
        options.addArguments("--headless");
        options.addArguments("--disable-gpu");
        options.addArguments("--window-size=1920,1080");
        options.addArguments("user-agent='MQQBrowser/26 Mozilla///5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'");
        // 关闭日志
        options.addArguments("--disable-logging");

        //屏蔽控制显示
        options.setExperimentalOption("useAutomationExtension", false);
        //突破网站检测
        options.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));

        WebDriver driver = new ChromeDriver(options);
        LogUtil.log("WebDriver 加载完成--------------"   chromeDriver);
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS);
        return driver;
    }

    public  WebDriver initJsWebDriver() {
        String driverPath1 = getYmlPath(driverPath);
        DesiredCapabilities desiredCapabilities = DesiredCapabilities.phantomjs();
        desiredCapabilities.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, driverPath1);
        desiredCapabilities.setCapability(CapabilityType.ELEMENT_SCROLL_BEHAVIOR, true);
        desiredCapabilities.setCapability(CapabilityType.TAKES_SCREENSHOT, true);
        desiredCapabilities.setCapability(CapabilityType.ENABLE_PROFILING_CAPABILITY, true);
        desiredCapabilities.setCapability(CapabilityType.HAS_NATIVE_EVENTS, true);

        desiredCapabilities.setJavascriptEnabled(false);

        ArrayList<String> cliArgs = new ArrayList<String>();
        cliArgs.add("--web-security=true");
        cliArgs.add("--ignore-ssl-errors=true");
        desiredCapabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, cliArgs);
        return new PhantomJSDriver(desiredCapabilities);
    }


    public BufferedImage loadPageByElement(WebDriver driver, SeleniumWConfInfo seleniumWConfInfo) throws IOException, InterruptedException {
        driver.get(seleniumWConfInfo.getUrl());//打开指定的网站
        // TODO  在前端添加 加载功能后 可以设置等待前端加载功能小时为标记
        ExpectedCondition<?> expectedCondition = seleniumWConfInfo.waitByElement();
        if (expectedCondition != null)
            (new WebDriverWait(driver, 50)).until(expectedCondition);//检查到访问成功
        WebElement element = driver.findElement(By.className("pcg-info"));
        int height1 = Integer.parseInt((String) ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight.toString()"));
        int width = Integer.parseInt((String) ((JavascriptExecutor) driver).executeScript("return document.body.scrollWidth.toString()"));
        driver.manage().window().setSize(new Dimension(width, height1));
        List<String> files = new ArrayList<String>();
        files.add(screenshot(driver, element).getAbsolutePath());
        driver.quit();//退出浏览器
        return merge(files.toArray(new String[]{}));
    }

    public BufferedImage loadPageByScroll(WebDriver driver, SeleniumWConfInfo seleniumWConfInfo) throws IOException, InterruptedException {
        driver.get("http://scidev.lenovo.com/web/main/dynamic/data-migration-connection-info");//打开指定的网站
        int height1 = Integer.parseInt((String) ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight.toString()"));
        int width = Integer.parseInt((String) ((JavascriptExecutor) driver).executeScript("return document.body.scrollWidth.toString()"));
        driver.manage().window().setSize(new Dimension(width, height1));
        String js1 = "return document.body.clientHeight.toString()";
        JavascriptExecutor executor = (JavascriptExecutor) driver;
        String js1_result = executor.executeScript(js1)   "";
        int height = Integer.parseInt(js1_result);
        List<String> files = new ArrayList<String>();
        int last_t = 0;
        for (int i = 0; i < 20; i  ) {
            int currentHeight = (i * height);
            String js = "window.scrollTo(0,"   currentHeight   ");";
            executor.executeScript(js);
            int real_top = Integer.parseInt(js1_result.split(",")[0]);
            if (real_top == currentHeight) {
                //  #如果这次设置的top成功,则继续滚屏
                i  ;
                files.add(screenshot(driver).getAbsolutePath());
                last_t = real_top;
            } else {
                // #如果本次设置失败,看这次的top和上一次记录的top值是否相等,相等则说明没有新加载内容,且已到页面底,跳出循环
                if (real_top != last_t) {
                    last_t = real_top;
                } else {
                    break;
                }
            }
        }
        driver.quit();//退出浏览器
        return merge(files.toArray(new String[]{}));
    }

    public void webDriverLogin(WebDriver driver, String logonUrl, SeleniumWConfInfo seleniumWConfInfo) {
        //SeleniumAccountInfo seleniumAccountInfo = accountInfoMapper.getAccountById(seleniumWConfInfo.getUserId());
        //进入登录页面
        driver.get(logonUrl);
        driver.findElement(By.name("username")).sendKeys("zhangbin38");
        driver.findElement(By.name("password")).sendKeys("666666");
        //登录
        driver.findElement(By.className("submit")).click();
        //检查到登录成功
        (new WebDriverWait(driver, 50)).until(ExpectedConditions.presenceOfElementLocated(By.className("home")));
    }

    public void webDriverLogin(WebDriver driver, String logonUrl, HttpServletRequest request) {
        //进入登录页面
        driver.get(logonUrl);
        //注入已登录Cookies
        Arrays.stream(request.getCookies()).map(c -> new Cookie(c.getName(), c.getValue(), c.getDomain(), c.getPath(), new Date(System.currentTimeMillis()   10000L))).forEach(driver.manage()::addCookie);
    }

    private static File screenshot(WebDriver driver) throws InterruptedException, IOException {
        try {
            driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Thread.sleep(5000);//等等页面加载完成
        byte[] imageBytes = (byte[]) ((ChromeDriver) driver).getScreenshotAs(new OutputType<Object>() {
            public Object convertFromBase64Png(String s) {
                try {
                    return (new BASE64Decoder()).decodeBuffer(s);
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            }

            public Object convertFromPngBytes(byte[] bytes) {
                return bytes;
            }
        });
        ByteArrayInputStream bytes = new ByteArrayInputStream(imageBytes);
        BufferedImage image = ImageIO.read(bytes);
        File file = File.createTempFile((new Random()).nextInt()   "", type);
        ImageIO.write(image, "png", file);
        return file;
    }

    private File screenshot(WebDriver driver, WebElement element) throws InterruptedException, IOException {
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        Thread.sleep(5000);//等等页面加载完成
        File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
        Point p = element.getLocation();
        Rectangle rect = new Rectangle(element.getSize().getWidth(), element.getSize().getHeight());
        BufferedImage img = ImageIO.read(scrFile);
        BufferedImage dest = img.getSubimage(p.getX(), p.getY(),
                (int) rect.getWidth(), (int) rect.getHeight());
        File file = File.createTempFile((new Random()).nextInt()   "", type);
        ImageIO.write(dest, "png", file);
        return file;
    }

    
    public BufferedImage merge(String[] pics) {
        int len = pics.length;
        if (len < 1) {
            return null;
        }
        File[] src = new File[len];
        BufferedImage[] images = new BufferedImage[len];
        int[][] ImageArrays = new int[len][];
        for (int i = 0; i < len; i  ) {
            try {
                src[i] = new File(pics[i]);
                images[i] = ImageIO.read(src[i]);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            int width = images[i].getWidth();
            int height = images[i].getHeight();
            ImageArrays[i] = new int[width * height];// 从图片中读取RGB
            ImageArrays[i] = images[i].getRGB(0, 0, width, height,
                    ImageArrays[i], 0, width);
        }

        int dst_height = 0;
        int dst_width = images[0].getWidth();
        for (BufferedImage image : images) {
            dst_width = Math.max(dst_width, image.getWidth());

            dst_height  = image.getHeight();
        }
        if (dst_height < 1) {
            return null;
        }
        BufferedImage ImageNew = new BufferedImage(dst_width, dst_height,
                BufferedImage.TYPE_INT_RGB);
        // 生成新图片
        try {
            int height_i = 0;
            for (int i = 0; i < images.length; i  ) {
                ImageNew.setRGB(0, height_i, dst_width, images[i].getHeight(),
                        ImageArrays[i], 0, dst_width);
                height_i  = images[i].getHeight();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            for (String tempFile : pics) {
                File t = new File(tempFile);
                t.delete();
            }
        }
        return ImageNew;
    }

    public String uploadImage(BufferedImage image, String picName) {
        ByteArrayOutputStream out = null;
        InputStream imgin = null;
        String imgfileUrl = "";
        try {
            out = new ByteArrayOutputStream();
            ImageIO.write(image, "png", out);
            imgin = new ByteArrayInputStream(out.toByteArray());
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(imgin.available());
            objectMetadata.setContentType("multipart/form-data");
            imgfileUrl = S3Connection.uploadToS3(imgin, picName, objectMetadata);
            imgfileUrl = Optional.ofNullable(imgfileUrl).orElse("").split("\?")[0];
            return imgfileUrl;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (imgin != null) {
                try {
                    imgin.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return imgfileUrl;
    }

    public ObjectMetadata getObjectMetadata(InputStream in) throws IOException {
        ObjectMetadata objectMetadataPdf = new ObjectMetadata();
        objectMetadataPdf.setContentLength(in.available());
        objectMetadataPdf.setContentType("multipart/form-data");
        return objectMetadataPdf;
    }

    public String getYmlPath(String driverPath) {
        String[] paths = driverPath.split(",");
        String osName = System.getProperty("os.name");
        String filePath = paths[0];
        if (osName.toUpperCase().startsWith("LIN")) {
            filePath = paths[0];
        } else {
            filePath = paths[1];
        }
        URL resource = Thread.currentThread().getContextClassLoader().getResource(filePath);
        String finalFilePath = filePath;
        filePath = Optional.ofNullable(resource).orElseThrow(() -> new NullPointerException(finalFilePath)).getPath();
        System.out.println("driver--------------"   filePath);
        return filePath;
    }

    public static WebDriver createFireFoxDriver() {
        System.setProperty("webdriver.gecko.driver","D://geckodriver.exe");
        FirefoxProfile firefoxProfile = new FirefoxProfile();
        //firefoxProfile.setEnableNativeEvents(true);
        firefoxProfile.setAcceptUntrustedCertificates(true);
        firefoxProfile.setPreference("layers.acceleration.disabled", true);
        firefoxProfile.setPreference("permissions.default.stylesheet", 2);
        firefoxProfile.setPreference("permissions.default.image", 2);
        DesiredCapabilities desiredCapabilities = DesiredCapabilities.firefox();
        desiredCapabilities.setCapability(FirefoxDriver.PROFILE, firefoxProfile);
        //desiredCapabilities.setCapability("webdriver.firefox.bin","D://geckodriver.exe");
        return new FirefoxDriver(desiredCapabilities);
    }

    public static void main(String[] args) throws InterruptedException, IOException {
        /*DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
        //ssl证书支持
        desiredCapabilities.setCapability("acceptSslCerts", true);
        //截屏支持
        desiredCapabilities.setCapability("takesScreenshot", true);
        //css搜索支持
        desiredCapabilities.setCapability("cssSelectorsEnabled", true);
        //js支持
        desiredCapabilities.setJavascriptEnabled(true);
        //驱动支持
        desiredCapabilities.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY,"D:\phantomjs-2.1.1-windows\bin\phantomjs.exe");
        //创建无界面浏览器对象
        String [] phantomJsArgs = {"--ignore-ssl-errors=true","--ssl-protocol=tlsv1"};
        desiredCapabilities.setCapability(
                PhantomJSDriverService.PHANTOMJS_CLI_ARGS,
                phantomJsArgs);
        //WebDriver driver = createFireFoxDriver();
        //WebDriver webDriver = new PhantomJSDriver(desiredCapabilities);
        WebDriver driver = new PhantomJSDriver(desiredCapabilities);
        driver.get("http://scidev.lenovo.com/web/user/login");

        Thread.sleep(500);//等等页面加载完成
        System.out.println(driver.getCurrentUrl());
        System.out.println(driver.getPageSource());

        *//*driver.findElement(By.name("username")).sendKeys("zhangbin38");
        driver.findElement(By.name("password")).sendKeys("666666");
        driver.findElement(By.className("submit")).click();*//*
        //检查到登录成功
        (new WebDriverWait(driver, 50)).until(ExpectedConditions.presenceOfElementLocated(By.className("home")));
        screenshot(driver);
    }*/

        // 设置驱动地址
        System.setProperty("webdriver.chrome.driver",
                "D:\chromedriver.exe");
        ChromeOptions options = new ChromeOptions();
// 设置谷歌浏览器exe文件所在地址
        options.setBinary("C:\Program Files (x86)\Google\Chrome\Application\chrome.exe");
// 这里是要执行的命令,如需修改截图页面的尺寸,修改--window-size的参数即可
                options.addArguments("--headless", "--disable-gpu", "--window-size=1920,1200", "--ignore-certificate-errors");
        WebDriver driver = new ChromeDriver(options);
// 访问页面
        driver.get("https://www.baidu.com");
// 页面等待渲染时长,如果你的页面需要动态渲染数据的话一定要留出页面渲染的时间,单位默认是秒
        Wait<WebDriver> wait = new WebDriverWait(driver, 3);
        wait.until(new ExpectedCondition<WebElement>() {
            public WebElement apply(WebDriver d) {
                //等待前台页面中 id为“kw”的组件渲染完毕,后截图
//若无需等待渲染,return true即可。 不同页面视情况设置id
                return d.findElement(By.id("kw"));
            }
        });
// 获取到截图的文件
        File screenshotFile = ((TakesScreenshot) driver)
                .getScreenshotAs(OutputType.FILE);
        if ((screenshotFile != null) && screenshotFile.exists()) {
            //截取到的图片存到本地
            FileOutputStream out = null;
            FileInputStream in = null;
            try {
                in = new FileInputStream(screenshotFile);
                out = new FileOutputStream("D:\headless\cut1.png");
                byte[] b = new byte[1024];
                while (true) {
                    int temp = in.read(b, 0, b.length);
                    // 如果temp = -1的时候,说明读取完毕
                    if (temp == -1) {
                        break;
                    }
                    out.write(b, 0, temp);
                }
            } catch (Exception e) {
                //TODO异常处理
            }
        }
    }

}

0 人点赞