前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PhantomJS,chrome,firefox 驱动截取图片

PhantomJS,chrome,firefox 驱动截取图片

原创
作者头像
binc
发布2021-12-13 10:49:47
1.2K0
发布2021-12-13 10:49:47
举报
文章被收录于专栏:技术分享-java
代码语言: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异常处理
            }
        }
    }

}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档