首页 > 编程语言 >java 实现网址的截图

java 实现网址的截图

时间:2023-09-04 14:33:25浏览次数:354  
标签:截图 java String process driver 网址 new import options

 

maven 引入

<!--自动化测试工具,需要去其他网址下第三方包-->
<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-java</artifactId>
  <version>3.141.59</version>
   <exclusions>
    <exclusion>
     <artifactId>guava</artifactId>
     <groupId>com.google.guava</groupId>
    </exclusion>
   </exclusions>
  </dependency>
  <dependency>
  <groupId>com.google.guava</groupId>
   <artifactId>guava</artifactId>
    <version>23.0</version>
    </dependency>
   <dependency>
   <groupId>com.google.code.gson</groupId>
     <artifactId>gson</artifactId>
    <version>2.8.2</version>
  </dependency>

  

下载相关浏览器chrome

(windows)https://www.chromedownloads.net/chrome64win/
windows会自己更新,需要自己去禁止更新,不然测着测着,浏览器升级了(除非你旧版本打开以后,就不要关闭),导致代码报错

(linux)https://www.chromedownloads.net/chrome64linux/
linux系统不会自动更新的,不要担心

下载相关浏览器chromedriver驱动

我这边下载的也是98.0.4758.102版本
https://registry.npmmirror.com/binary.html?path=chromedriver/98.0.4758.102/

 

测试代码

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.epoint.third.apache.commons.io.FileUtils;
import com.linewell.gov.hoox.utils.log.LogUtil;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;

import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 条件:需要谷歌浏览器版本和驱动版本一张
 */
public class SeleniumTools {

    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        Timestamp now1 = new Timestamp(startTime);
        System.out.println("now1:" + now1);
        for (int i = 0; i < 3; i++) {
            try {
                guge("D:/guge/img"+"/"+System.currentTimeMillis()+".png",
                        "https://mpage.taobao.com/hd/download.html",
                        "123");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        long between = DateUtil.between(new Date(startTime), new Date(), DateUnit.SECOND);
        System.out.println("相差秒"+between);
        System.out.println("相差分钟"+between/60);


    }


    //解决如下: 模拟浏览器滚动滚动条 解决懒加载问题
    public static void guge(String hzdtpwzPath, String url, String nhhzdtoken) throws IOException {
        LogUtil.info("=====guge=========");
        LogUtil.info(hzdtpwzPath);
        LogUtil.info(url);
        LogUtil.info(nhhzdtoken);
        // 根据系统来添加不同的驱动路径
        String os = System.getProperty("os.name");
        LogUtil.info(os);
        String driverPath ="";
        if (StrUtil.containsIgnoreCase(os, "Windows")) {//微软系统
            driverPath+="D:\\chromedriver_win32 (98.0.4758.102)\\chromedriver.exe";
        //程序执行,核心代码
            processCMD("taskkill /F /im chromedriver.exe",1);
        } else {//linux系统
            driverPath+="/usr/local/xxxx/ChromeDriver/chromedriver_linux64/chromedriver";
            //程序执行,核心代码
            processCMD("ps -ef | grep Chrome | grep -v grep  | awk '{print \"kill -9 \"$2}' | sh",2);
        }

        //频繁的启动关闭,会增加一个比较明显的延时导致浏览器进程不被关闭的情况发生,
        // 为了避免这一状况我们可以通过ChromeDriverService来控制ChromeDriver进程的生死,
        // 达到用完就关闭的效果避免进程占用情况出现(Running the  server in a child process)
        ChromeDriverService service =new  ChromeDriverService.Builder().usingDriverExecutable(new File(driverPath)).usingAnyFreePort().build(); // 新建service 方便后面关闭chromedriver
        service.start(); // 开启服务

        ChromeOptions options = new ChromeOptions();
        //ssl证书支持
        options.setCapability("acceptSslCerts", true);
        //截屏支持
        options.setCapability("takesScreenshot", true);
        //css搜索支持
        options.setCapability("cssSelectorsEnabled", true);
        //设置浏览器参数
        // 设置无轨 开发时还是不要加,可以看到浏览器效果
        options.addArguments("--headless");
        options.addArguments("--no-sandbox");
        options.addArguments("--disable-gpu");
        options.addArguments("--disable-dev-shm-usage");
        //处理僵尸进程
        options.addArguments("--no-zygote");
        //设置无头模式,一定要设置headless,否则只能截出电脑屏幕大小的图!!!
        options.setHeadless(true);
        WebDriver driver = new ChromeDriver(service,options);
        //设置超时,避免有些内容加载过慢导致截不到图
        driver.manage().timeouts().pageLoadTimeout(1, TimeUnit.MINUTES);
        driver.manage().timeouts().implicitlyWait(1, TimeUnit.MINUTES);
        driver.manage().timeouts().setScriptTimeout(1, TimeUnit.MINUTES);
        try {
            //设置需要访问的地址
            driver.get(url);
            //先登录,再设置cookies
            Cookie c1 = new Cookie("token", nhhzdtoken);
            driver.manage().addCookie(c1);
            //设置需要访问的地址
            driver.get(url);
            //获取高度和宽度一定要在设置URL之后,不然会导致获取不到页面真实的宽高;
            Long width = (Long) ((ChromeDriver) driver).executeScript("return document.documentElement.scrollWidth");
            Long height = (Long) ((ChromeDriver) driver).executeScript("return document.documentElement.scrollHeight");
            LogUtil.info("宽带:" + width);
            LogUtil.info("高度:" + height);
            //这里需要模拟滑动,有些是滑动的时候才加在的
            long temp_height = 0;
            while (true) {
                //每次滚动500个像素,因为懒加载所以每次等待2S 具体时间可以根据具体业务场景去设置
                Thread.sleep(1000);
                ((ChromeDriver) driver).executeScript("window.scrollBy(0,500)");
                temp_height += 500;
                if (temp_height >= height) {
                    break;
                }
            }
            //设置窗口宽高,设置后才能截全
            driver.manage().window().setSize(new Dimension(width.intValue()+1120, height.intValue()+303));
            //设置截图文件保存的路径
            String screenshotPath = hzdtpwzPath;
            File srcFile = ((ChromeDriver) driver).getScreenshotAs(OutputType.FILE);
            FileUtils.copyFile(srcFile, new File(screenshotPath));
            LogUtil.info("设置浏览器截图文件保存的路径:" + screenshotPath);
        } catch (Exception e) {
            throw new RuntimeException("截图失败", e);
        } finally {
            //close仅仅关闭了当前页面,并未关闭chrome。
            //使用quit则会真正退出chrome,结束进程。
            //两者一起使用,才能避免频繁的启动关闭出现的卡住现象(重点)
            driver.close();
            driver.quit();
            service.stop();
        }
    }

    //直接杀进程
    public static int processCMD(String commend,int type) {
        //正常写 linux命令即可 、比如:mkdir xx/touch b.txt/sh start.sh/sh stop.sh
        int i = 0;
        Process process =null;
        //程序执行,核心代码
        try {
            if(type==1){
                //cmd /c dir 是执行完dir命令后关闭命令窗口。看需调整
                String[] cmd = new String[]{"cmd","/c",commend};
                process = Runtime.getRuntime().exec(cmd);
                //也可以直接使用 process = Runtime.getRuntime().exec(commend)
            }else{
                //要想保证linux环境下命令能够执行成功,必须使用String[]
                String[] cmd = new String[]{"sh","-c",commend};
                process = Runtime.getRuntime().exec(cmd);
            }
            i = process.waitFor();
            System.out.println("执行kill进程命令结果:" + i);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return i;
    }


    //通常,安全编码规范中都会指出:使用Process.waitFor()的时候,
    //可能导致进程阻塞,甚至死锁。
    //使用java代码执行shell脚本,执行后会发现Java进程和Shell进程都会挂起,无法结束。
    public static int processCMD2(String commend) {
        //正常写 linux命令即可 、比如:mkdir xx/touch b.txt/sh start.sh/sh stop.sh
        int i = 0;
        Process process = null;
        try {
            process = Runtime.getRuntime().exec(commend);
            //获取进程的标准输入流
            final InputStream is1 = process.getInputStream();
            //获取进城的错误流
            final InputStream is2 = process.getErrorStream();
            //启动两个线程,一个线程负责读标准输出流,另一个负责读标准错误流
            new Thread(() -> {
                BufferedReader br1 = new BufferedReader(new InputStreamReader(is1));
                try {
                    String line1 = null;
                    while ((line1 = br1.readLine()) != null) {
                        if (line1 != null) {
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        is1.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();

            new Thread(() -> {
                BufferedReader br2 = new BufferedReader(new InputStreamReader(is2));
                try {
                    String line2 = null;
                    while ((line2 = br2.readLine()) != null) {
                        if (line2 != null) {
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        is2.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();

            //可能导致进程阻塞,甚至死锁
            i = process.waitFor();
        } catch (Exception ex) {
            ex.printStackTrace();
            try {
                process.getErrorStream().close();
                process.getInputStream().close();
                process.getOutputStream().close();
            } catch (Exception ee) {
            }
        }
        LogUtil.info("CMD2-执行kill进程命令:" + commend);
        System.out.println("CMD2-执行kill进程命令:" + commend);
        LogUtil.info("CMD2-执行kill进程命令结果:" + i);
        System.out.println("CMD2-执行kill进程命令结果:" + i);
        return i;
    }

}

  

 

转自 https://blog.csdn.net/qq_20236937/article/details/132231095

标签:截图,java,String,process,driver,网址,new,import,options
From: https://www.cnblogs.com/ysyy/p/17676937.html

相关文章

  • 【校招VIP】前端JavaScript语言之跨域
    考点介绍:什么是跨域?浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域。跨域是前端校招的一个重要考点,在面试过程中经常遇到,需要着重掌握。本期分享的前端算法考点之大数据相关,分为试题、文章以及视频三部分。答案详情解析和文章内容可点击下方......
  • 无涯教程-JavaScript - CUBEMEMBER函数
    描述CUBEMEMBER函数从多维数据集返回一个成员或元组。使用此函数可以验证多维数据集中是否存在成员或元组。语法CUBEMEMBER(connection,member_expression,[caption])争论Argument描述Required/OptionalconnectionNameoftheconnectiontothecube-Atextstr......
  • java实现发邮件功能的三种方式
    在Java中,有多种不同的方法可以实现发送邮件的功能。以下是几种常用的方法:使用JavaMailAPI:importjava.util.Properties;importjavax.mail.*;importjavax.mail.internet.*;publicclassEmailSender{publicstaticvoidsendEmail(Stringsender,Stringreceiver,Str......
  • 无涯教程-JavaScript - CUBEKPIMEMBER函数
    描述该函数返回关键绩效指标(KPI)属性,并在单元格中显示KPI名称。语法CUBEKPIMEMBER(connection,kpi_name,kpi_property,[caption])争论Argument描述Required/OptionalconnectionNameoftheconnectiontothecube-AtextstringRequiredkpi_nameNameoft......
  • Java语言基础知识全总结
    一.Java的优点1.      跨平台性。一次编译,到处运行。Java编译器会将Java代码编译成能在JVM上直接运行的字节码文件,C++会将源代码编译成可执行的二进制代码文件,所以C++执行速度快2.      纯面向对象。Java所有的代码都必须在类中书写。C++兼具面向对象和面向过程的特......
  • Java元注解
    工作过程中遇到以下需求:校验某些类的某些字符串属性的长度。由于不想对所有的类和属性进行枚举检查,因此,我想通过在类上添加自定义注解的方式过滤出这些类以及属性。故学习一下Java的元注解。Java元注解这里需要说一下Java的内置注解,因为Java里有几个针对注解的注解,即元注解。@......
  • Java 20 maven项目基本配置
     pom.xml<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://ma......
  • Java 快速排序
    思路通过一趟排序将无序数组划分成独立的两部分,其中一部分的所有元素比另外一部分的所有元素都要小,然后再按此方法对这两部分元素分别进行快速排序,整个排序过程可以递归进行,以此达到整个无序数组变成有序数组的目的。快速排序主要分为以下步骤:从无序数组中取出一个元素作为基......
  • Java 二分查找
    思路问题描述:在采用顺序存储结构的有序数组中,查找目标元素,如果目标元素存在,返回对应的数组下标。假设查找的有序数组为升序,二分查找采用以下的思路进行解决:将数组中间位置的元素与目标元素比较,如果二者相等,则查找成功;否则,从中间位置将数组分为前、后两个数组;如果中间位置......
  • Java 归并排序
    思路数组排序主要分为两个部分:划分数组和归并排序。划分数组:将待排序的无序数组分为左右两个部分,如果无序数组的起始元素下标为first,最后一个元素的下标为last,那么左右两部分之间的临界点下标mid=(first+last)/2,这两部分分别是arr[first…mid]和arr[mid+1…last];将上......