Java 成功实现通过网址URL截图保存

Java 实现通过网址URL截图

    • 1.DjNativeSwing方式 (不好用)
    • 2.phantomjs方式 (截图还是有瑕疵)
    • 3.selenium方式 (满意,成功实现)
      • maven 引入
      • 下载相关浏览器chrome
      • 下载相关浏览器chromedriver驱动
      • 后端代码

1.DjNativeSwing方式 (不好用)

实操 DjNativeSwing 方式 的现象
1.截图效果(非百度网页):有图片,排版正常,但是部分样式丢失(输入框的文字掉下去了)
2.main 方法使用的里面没问题 ,但是springboot项目去启动以后,该方式触发报错
需要在启动类,关闭无头模式
3.本地项目成功实现以后
部署linux系统后,我这一块还是出现了 与“awt .headless”相关的错误
(1)Can’t connect to ll window server using ‘0.g’ as the value of the DISPLAY variable.
要我去配置
JAVA OPTS=-Djava.awt.headless=true
可我本地程序需要关闭才能用,怎么linux上面又让我开启
想了想是不是,打包上我改成本地要开启,结果发布上linux还是不行
耗费太长时间,想了想,截出来的图是有瑕疵问题,索性直接放弃了该方式

参考文章
(1)https://codeleading.com/article/3074321735/
(2)https://blog.51cto.com/binghe001/5243790
(3)https://www.cnblogs.com/lsy-blogs/p/7700564.html
(4)https://blog.csdn.net/ljj9oo9/article/details/8771670

<dependency>
   <groupId>com.hynnet</groupId>
   <artifactId>DJNativeSwing</artifactId>
   <version>1.0.0</version>
</dependency>
<dependency>
    <groupId>com.hynnet</groupId>
    <artifactId>DJNativeSwing-SWT</artifactId>
    <version>1.0.0</version>
</dependency>
        <!--win64-->
        <dependency>
            <groupId>org.eclipse.swt</groupId>
            <artifactId>org.eclipse.swt.win32.win32.x86_64</artifactId>
            <version>4.3</version>
        </dependency>
        <!--linux-->
<!--        <dependency>-->
<!--            <groupId>org.eclipse.swt</groupId>-->
<!--            <artifactId>org.eclipse.swt.gtk.linux.x86_64</artifactId>-->
<!--            <version>4.3</version>-->
<!--            <scope>provided</scope>-->
<!--        </dependency>-->
import chrriis.dj.nativeswing.swtimpl.NativeComponent;
import chrriis.dj.nativeswing.swtimpl.NativeInterface;
import chrriis.dj.nativeswing.swtimpl.components.JWebBrowser;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserAdapter;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserEvent;
import com.linewell.gov.hoox.utils.log.LogUtil;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

/**
 * Created with CosmosRay
 * 条件:需要给启动类,关闭无头模式,
 * 缺陷:部分网址,截图样式部分还是有问题
 * @author CosmosRay
 * @date 2019/5/22
 * Function:
 */
public class DjNativeSwingUtil extends JPanel {
    // 行分隔符
    final static public String LS = System.getProperty("line.separator", "\n");
    // 文件分割符
    final static public String FS = System.getProperty("file.separator", "\\");
    // 以javascript脚本获得网页全屏后大小
    private static final long serialVersionUID = 1L;
    private static final StringBuffer jsDimension;

    static {
        jsDimension = new StringBuffer();
        jsDimension.append("var width = 0;").append(LS);
        jsDimension.append("var height = 0;").append(LS);
        jsDimension.append("if(document.documentElement) {").append(LS);
        jsDimension.append("  width = Math.max(width, document.documentElement.scrollWidth);").append(LS);
        jsDimension.append("  height = Math.max(height, document.documentElement.scrollHeight);").append(LS);
        jsDimension.append("}").append(LS);
        jsDimension.append("if(self.innerWidth) {").append(LS);
        jsDimension.append("  width = Math.max(width, self.innerWidth);").append(LS);
        jsDimension.append("  height = Math.max(height, self.innerHeight);").append(LS);
        jsDimension.append("}").append(LS);
        jsDimension.append("if(document.body.scrollWidth) {").append(LS);
        jsDimension.append("  width = Math.max(width, document.body.scrollWidth);").append(LS);
        jsDimension.append("  height = Math.max(height, document.body.scrollHeight);").append(LS);
        jsDimension.append("}").append(LS);
        jsDimension.append("return width + ':' + height;");
    }

    public DjNativeSwingUtil( String url, String token, String fileName, int maxWidth,  int maxHeight) {
        super(new BorderLayout());
        //面板
        LogUtil.info("DjNativeSwingUtil-面板进入");
        JPanel webBrowserPanel = new JPanel(new BorderLayout());
        final JWebBrowser webBrowser = new JWebBrowser(null);
        webBrowser.setBarsVisible(false);
        //设置cooker
        webBrowser.setCookie(url, "token=" + token);
        webBrowser.navigate(url);
        webBrowserPanel.add(webBrowser, BorderLayout.CENTER);
        add(webBrowserPanel, BorderLayout.CENTER);

        JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 4, 4));

        webBrowser.addWebBrowserListener(new WebBrowserAdapter() {
                                             // 监听加载进度
                                             @Override
                                             public void loadingProgressChanged(WebBrowserEvent e) {
                                                 // 当加载完毕时
                                                 if (e.getWebBrowser().getLoadingProgress() == 100) {
                                                     /*睡眠3秒钟,等待页面请求完毕再截取图片信息
                                                      * 如果不延时,则图片等可能没有时间下载显示
                                                      * 具体的秒数需要根据网速等调整
                                                      * */
                                                     try {
                                                         Thread.sleep(3000);
                                                     } catch (InterruptedException e1) {
                                                         e1.printStackTrace();
                                                     }
                                                     String result = (String) webBrowser.executeJavascriptWithResult(jsDimension.toString());
                                                     int index = result == null ? -1 : result.indexOf(":");
                                                     NativeComponent nativeComponent = webBrowser.getNativeComponent();
                                                     Dimension originalSize = nativeComponent.getSize();
                                                     Dimension imageSize = new Dimension(Integer.parseInt(result.substring(0, index)), Integer.parseInt(result
                                                             .substring(index + 1)));
//                                                     imageSize.width = Math.max(originalSize.width, imageSize.width + 50);
//                                                     imageSize.height = Math.max(originalSize.height, imageSize.height + 50);
                                                     imageSize.width = maxWidth;
                                                     imageSize.height = maxHeight;

                                                     nativeComponent.setSize(imageSize);
                                                     BufferedImage image = new BufferedImage(imageSize.width,
                                                             imageSize.height, BufferedImage.TYPE_INT_RGB);
                                                     nativeComponent.paintComponent(image);
                                                     nativeComponent.setSize(originalSize);
                                                     try {
                                                         // 输出图像
                                                         System.out.println(fileName);
                                                         ImageIO.write(image, "png", new File(fileName));
                                                     } catch (IOException ex) {
                                                         ex.printStackTrace();
                                                     }
                                                     // 退出操作 (会把整个springboot项目都杀掉)
                                                     //System.exit(0);
                                                 }
                                             }
                                         }
        );
        add(panel, BorderLayout.SOUTH);
    }

    public static void main(String[] args) {
        NativeInterface.open();
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                // SWT组件转Swing组件,不初始化父窗体将无法启动webBrowser
                javax.swing.JFrame frame = new javax.swing.JFrame("以DJ组件保存指定网页截图");
                // 加载google,最大保存为640x480的截图
                //实际项目中传入URL参数,根据不同参数截取不同网页快照,保存地址也可以在构造器中多设置一个参数,保存到指定目录
                frame.getContentPane().add(new DjNativeSwingUtil(
                        "https://www.baidu.com",
                        null,
                        "D:\\" + System.currentTimeMillis() + ".png",
                        1800, 1300
                ), BorderLayout.CENTER);
                frame.setSize(2200, 1800);

                // 仅初始化,但不显示
                frame.invalidate();
                frame.pack();
                //隐藏并释放内存,并不一定结束整个应用程序
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                //将窗口隐藏(但窗口的相关资源仍然存在)
                frame.setVisible(false);
            }
        });
        NativeInterface.runEventPump();
    }
}

2.phantomjs方式 (截图还是有瑕疵)

实操 phantomjs 方式 的现象
截图效果(非百度网页):有图片,排版稍微有点问题,样式正常,但是有些文字居然少了一截
虽然不用搞什么“无头”模式子类的了,但是我看到本地截图效果还是选择放弃使用这种方式

PlantomJs是一个基于javascript的webkit内核无头浏览器 也就是没有显示界面的浏览器,你可以在基于 webkit 浏览器做的事情,它都能做到。PlantomJs提供了如 CSS 选择器、DOM操作、JSON、HTML5、Canvas、SVG 等。
PhantomJS 的用处很广泛,如网络监控、网页截屏、页面访问自动化、无需浏览器的 Web 测试等,这里只用到网页截屏。
PlantomJs可以通过官网下载http://phantomjs.org/download.html,
也可以通过(只有windows版本):https://pan.baidu.com/s/1EVX1RPX7gY0rGvEI6OHcwg 密码:brb4 下载;解压后可以看到

参考链接
(1)Java实现网页截屏功能(基于phantomJs)https://www.cnblogs.com/han108/p/9216583.html#:~:text=var%20page%20%3D%20require%20%28%27webpage%27%29.create%20%28%29%2C%20system%20%3D,%28output%29%3B%20phantom.exit%20%28%29%3B%20%7D%2C%20200%29%3B%20%7D%20%7D%29%3B%20%7D
(2)完美解决java截图网页并保存到数据库中预览
https://blog.csdn.net/qq_43665446/article/details/129312799?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-3-129312799-blog-37992055.235%5Ev38%5Epc_relevant_anti_vip&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-3-129312799-blog-37992055.235%5Ev38%5Epc_relevant_anti_vip&utm_relevant_index=4
(3)phantom添加cookie
https://www.ngui.cc/el/2578032.html?action=onClick
(4)使用phantomjs对网页截图
https://blog.csdn.net/FreemanZhao/article/details/77498749
(5)selenium+phantomjs截长图踩坑
https://blog.csdn.net/u014307117/article/details/108187245

下载好后的“D:\phantomjs-2.1.1-windows”文件夹里面的 “examples”文件夹里面有个rasterize.js文件,用下面这个内容替代掉即可

rasterize.js
如果要加cookie,要特别注意"domain"这个值是必传且不能随便乱传,和你要截图的地址相关,不然会报错的

var page = require('webpage').create(),
    system = require('system'),
    address, output, size;

//可以带cookie
//var flag = phantom.addCookie({
//        "domain": ".baidu.com" ,
//        "expires": "Fri, 01 Jan 2038 00:00:00 GMT",
//        "expiry": 2145916800,
//        "httponly": false,
//        "name": "token",
//        "path": "/",
//        "secure": false,
//        "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOiJud19kemdkIiwiRXhwaXJlIjoiMjAyMy0wOC0xMCAxNDoyMzo0NyJ9.InsFJkcXI6C57r-1Oqb7PMn-OcP9k0W5lf1K896EasY"
//});

if (system.args.length < 3 || system.args.length > 5) {
    phantom.exit(1);
} else {
    address = system.args[1];//传入url地址
    output = system.args[2];//输出图片的地址
    page.viewportSize = { width: 800, height: 1800 };//自定义定义宽高
    if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
        size = system.args[3].split('*');
        page.paperSize = size.length === 2 ? { width: size[0], height: size[1], margin: '0px' }
                                           : { format: system.args[3], orientation: 'portrait', margin: '1cm' };
    } else if (system.args.length > 3 && system.args[3].substr(-2) === "px") {
        size = system.args[3].split('*');
        if (size.length === 2) {
            pageWidth = parseInt(size[0], 10);
            pageHeight = parseInt(size[1], 10);
            page.viewportSize = { width: pageWidth, height: pageHeight };
            page.clipRect = { top: 0, left: 0, width: pageWidth, height: pageHeight };
        } else {
            console.log("size:", system.args[3]);
            pageWidth = parseInt(system.args[3], 10);
            pageHeight = parseInt(pageWidth * 3/4, 10); // it's as good an assumption as any
            console.log ("pageHeight:",pageHeight);
            page.viewportSize = { width: pageWidth, height: pageHeight };
        }
    }
    if (system.args.length > 4) {
        page.zoomFactor = system.args[4];
    }
    page.open(address, function (status) {
        if (status !== 'success') {
            console.log('Unable to load the address!');
            phantom.exit(1);
        } else {
            window.setTimeout(function () {
                page.render(output);
                phantom.exit();
            }, 3000);
        }
    });
}

address = system.args[1];//传入url地址
output = system.args[2];//输出图片的地址
page.viewportSize = { width: 2000, height: 1300 };//自定义定义宽高

后端代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Scanner;

/**
 * @Description:根据网页地址转换成图片
 * @Author: admin
 *  条件:需要插件及js脚本
 *  缺陷:部分网址,截图样式部分还是有问题
 * @CreateDate: 2018年6月22日
 */
public class PhantomTools {
    private static String tempPath = "D:/temp/img";// 图片保存目录
    private static String BLANK = " ";
    // 下面内容可以在配置文件中配置
    private static String binPath = "D:\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe";// 插件引入地址
    private static String jsPath = "D:\\phantomjs-2.1.1-windows\\examples\\rasterize.js";// js引入地址

    private static String cookie = "token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOiJud19kemdkIiwiRXhwaXJlIjoiMjAyMy0wOC0xMCAxMzoxMTozMCJ9.IbO0oobfU5GTURuTnc7NyfnbMN-lkXalNEafDPXyzWE";// token

    // 执行cmd命令
    public static String cmd(String imgagePath, String url) {
        return binPath + BLANK + jsPath + BLANK + url + BLANK + imgagePath;
    }
    //关闭命令
    public static void close(Process process, BufferedReader bufferedReader) throws IOException {
        if (bufferedReader != null) {
            bufferedReader.close();
        }
        if (process != null) {
            process.destroy();
            process = null;
        }
    }
    /**
     * @param
     * @param url
     * @throws IOException
     */
    public static void printUrlScreen2jpg(String url) throws IOException{
        String imgagePath = tempPath+"/"+System.currentTimeMillis()+".png";//图片路径
        //Java中使用Runtime和Process类运行外部程序
        Process process = Runtime.getRuntime().exec(cmd(imgagePath,url));
        InputStream inputStream = process.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String tmp = "";
        while ((tmp = reader.readLine()) != null) {
            close(process,reader);
        }
        System.out.println("success");
    }

    public static void main(String[] args) throws IOException {
        String url = "https://www.baidu.com/";//以百度网站首页为例
        PhantomTools.printUrlScreen2jpg(url);
    }
}

3.selenium方式 (满意,成功实现)

实操 selenium 方式 的现象
截图效果(非百度网页):有图片,排版没问题,样式没问题
经测试决定使用它了

参考链接
(1)Java 实现通过网址URL截取整个网页的长图并保存(遇到的各种坑)
https://blog.csdn.net/Mli_Mi/article/details/116259669
(2)selenium+phantomjs截长图踩坑
https://blog.csdn.net/u014307117/article/details/108187245
(3)如何在linux系统执行java项目+selenium
https://blog.csdn.net/weixin_42736075/article/details/113444305?spm=1001.2014.3001.5506

maven 引入

1.请注意自己的项目里面是不是存在其他的“com.google.guava”版本,如果有请排除(全部排除),不然会出现所谓的
“com.google.common.util.concurrent.SimpleTimeLimiter.create(Ljava/util/concurrent/ExecutorService;)Lcom/google/common/util/concurrent/SimpleTimeLimiter;”
2.以下我选择的依赖版本是和后面的“浏览器版本”及“驱动版本”息息相关,
高版本亦或者低版本都可能会出现运行失败的现象

<!--自动化测试工具,需要去其他网址下第三方包-->
<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

我这边下载的是98.0.4758.102版本的浏览器(最新版本不容易配置)

(windows)https://www.chromedownloads.net/chrome64win/
在这里插入图片描述

(linux)https://www.chromedownloads.net/chrome64linux/
在这里插入图片描述

下载相关浏览器chromedriver驱动

我这边下载的也是98.0.4758.102版本
https://registry.npmmirror.com/binary.html?path=chromedriver/98.0.4758.102/
在这里插入图片描述

liunx服务器上面的安装相应的浏览器的执行命令

先cmd到你创建的目录下面,把linux版本chrome浏览器安装包移到下面,以上链接下载下来解压以后里面有两个版本的(rpm包和deb包)
rpm包相对来说版本不是最新的,但是比较稳定;
而deb包则相对来说版本比较新,一般某个新软件出来说可能有deb包,但是使用过程中容易引起bugs。
所以只留rpm包即可,放到linux的上面去

执行命令
cd到你放那个包的位置,然后执行安装命令

yum install 98.0.4758.102-google-chrome-stable_current_x86_64.rpm

后面会出现选择,输入“y” 确认安装即可

在这里插入图片描述

对于驱动文件也需要执行一下“可执行、读取”的命令

cd /usr/local/xxxx/ChromeDriver/chromedriver_linux64
chmod a+x chromedriver

再下载字体包,如果部分字体还是有问题,就需要去找字体包了
(我这边都是正常的字体,就没有去找其他的字体包了)

yum install mesa-libOSMesa-devel gnu-free-sans-fonts wqy-zenhei-fonts

后端代码

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 org.openqa.selenium.Cookie;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import java.io.File;
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 < 1; i++) {
            guge("D:/guge/img"+"/"+System.currentTimeMillis()+".png",
                    "https://mpage.taobao.com/hd/download.html",
                    "123");
        }
        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) {
        LogUtil.info("=====guge=========");
        LogUtil.info(hzdtpwzPath);
        LogUtil.info(url);
        LogUtil.info(nhhzdtoken);
        // 根据系统来添加不同的驱动路径
        String os = System.getProperty("os.name");
        LogUtil.info(os);
        if (StrUtil.containsIgnoreCase(os, "Windows")) {
            //这里设置下载的驱动路径,Windows对应chromedriver.exe Linux对应chromedriver,具体路径看你把驱动放在哪
            System.setProperty("webdriver.chrome.driver", "D:\\chromedriver_win32 (98.0.4758.102)\\chromedriver.exe");
        } else {
            // 只考虑Linux环境,需要下载对应版本的驱动后放置在绝对路径/usr/bin目录下
            System.setProperty("webdriver.chrome.driver", "/usr/local/xxxx/ChromeDriver/chromedriver_linux64/chromedriver");
        }
        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");
        //设置无头模式,一定要设置headless,否则只能截出电脑屏幕大小的图!!!
        options.setHeadless(true);
        ChromeDriver driver = new ChromeDriver(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) driver.executeScript("return document.documentElement.scrollWidth");
            Long height = (Long) driver.executeScript("return document.documentElement.scrollHeight");
            // 通过执行脚本解决Selenium截图不全问题
            //Long width = (Long) driver.executeScript(
            //        "return Math.max(document.body.scrollWidth, document.body.offsetWidth, document.documentElement.clientWidth, document.documentElement.scrollWidth, document.documentElement.offsetWidth);");
            //Long height = (Long) driver.executeScript(
            //        "return Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);");
            System.out.println("宽带:" + width);
            System.out.println("高度:" + height);
            //这里需要模拟滑动,有些是滑动的时候才加在的
            long temp_height = 0;
            while (true) {
                //每次滚动500个像素,因为懒加载所以每次等待2S 具体时间可以根据具体业务场景去设置
                Thread.sleep(1000);
                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 = driver.getScreenshotAs(OutputType.FILE);
            FileUtils.copyFile(srcFile, new File(screenshotPath));
        } catch (Exception e) {
            throw new RuntimeException("截图失败", e);
        } finally {
            driver.quit();
        }
    }

}

大功搞成了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/69153.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第53天|动态规划part11|123. 买卖股票的最佳时机 III、188.买卖股票的最佳时机IV

代码随想录算法训练营第53天&#xff5c;动态规划part11&#xff5c;123. 买卖股票的最佳时机 III、 188.买卖股票的最佳时机IV 123. 买卖股票的最佳时机 III 123. 买卖股票的最佳时机 III 思路&#xff1a; 相比买股票的最佳时机II&#xff0c;限制了买股票的次数&#xf…

Oracle 开发篇+Java调用OJDBC访问Oracle数据库

标签&#xff1a;JAVA语言、Oracle数据库、Java访问Oracle数据库释义&#xff1a;OJDBC是Oracle公司提供的Java数据库连接驱动程序 ★ 实验环境 ※ Oracle 19c ※ OJDBC8 ※ JDK 8 ★ Java代码案例 package PAC_001; import java.sql.Connection; import java.sql.ResultSet…

gitblit windows部署

1.官网下载 往死慢&#xff0c;我是从百度找的1.9.1&#xff0c;几乎就是最新版 http://www.gitblit.com/ 2.解压 下载下来是一个zip压缩包&#xff0c;直接解压即可 3.配置 3.1.配置资源库路径 找到data文件下的gitblit.properties文件&#xff0c;用Notepad打开 **注意路…

Android Ble蓝牙App(三)特性和属性

Ble蓝牙App&#xff08;三&#xff09;特性使用 前言正文一、获取属性列表二、属性适配器三、获取特性名称四、特性适配器五、加载特性六、显示特性和属性七、源码 前言 在上一篇中我们完成了连接和发现服务两个动作&#xff0c;那么再发现服务之后要做什么呢&#xff1f;发现服…

【二】数据库系统

数据库系统的分层抽象DBMS 数据的三个层次从 数据 到 数据的结构----模式数据库系统的三级模式&#xff08;三级视图&#xff09;数据库系统的两层映像数据库系统的两个独立性数据库系统的标准结构 数据模型从 模式 到 模式的结构----数据模型三大经典数据模型 数据库的演变与发…

windows使用/服务(13)戴尔电脑怎么设置通电自动开机

戴尔pc机器通电自启动 1、将主机显示器键盘鼠标连接好后&#xff0c;按主机电源键开机 2、在开机过程中按键盘"F12",进入如下界面&#xff0c;选择“BIOS SETUP” 3、选择“Power Management” 4、选择“AC Recovery”&#xff0c;点选“Power On”&#xff0c;点击“…

uniapp 格式化时间刚刚,几分钟前,几小时前,几天前…

效果如图&#xff1a; 根目录下新建utils文件夹&#xff0c;文件夹下新增js文件&#xff0c;文件内容&#xff1a; export const filters {dateTimeSub(data) {if (data undefined) {return;}// 传进来的data必须是日期格式&#xff0c;不能是时间戳//将字符串转换成时间格式…

使用 prometheus client SDK 暴露指标

目录 1. 使用 prometheus client SDK 暴露指标1.1. How Go exposition works1.2. Adding your own metrics1.3. Other Go client features 2. Golang Application monitoring using Prometheus2.1. Metrics and Labels2.2. Metrics Types2.2.1. Counters:2.2.2. Gauges:2.2.3. …

Python测试框架pytest:常用参数、查找子集、参数化、跳过

Pytest是一个基于python的测试框架&#xff0c;用于编写和执行测试代码。pytest主要用于API测试&#xff0c;可以编写代码来测试API、数据库、UI等。 pytest是一个非常成熟的全功能的Python测试框架&#xff0c;主要有以下几个优点&#xff1a; 简单灵活&#xff0c;容易上手。…

前端渲染数据

在前端对接受后端数据处理后返回的接收值的时候&#xff0c;为了解决数据过于庞大&#xff0c;而对数据进行简化处理例如性别&#xff0c;经常会使用1&#xff0c; 0这俩个来代替文字的男&#xff0c;女。以下就是前端渲染的具体实现。 以下是部分代码 <el-table-columnpr…

【MFC】10.MFC六大机制:RTTI(运行时类型识别),动态创建机制,窗口切分,子类化-笔记

运行时类信息&#xff08;RTTI&#xff09; C: ##是拼接 #是替换成字符串 // RTTI.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <afxwin.h>#ifdef _DEBUG #define new DEBUG_NEW #endifCWinApp th…

ubuntu 安装 nvidia 驱动

ubuntu 安装 nvidia 驱动 初环境与设备查询型号查询对应的驱动版本安装驱动验证驱动安装结果 本篇文章将介绍ubuntu 安装 nvidia 驱动 初 希望能写一些简单的教程和案例分享给需要的人 环境与设备 系统&#xff1a;ubuntu 设备&#xff1a;Nvidia GeForce RTX 4090 查询型…

Tcp是怎样进行可靠准确的传输数据包的?

概述 很多时候&#xff0c;我们都在说Tcp协议&#xff0c;Tcp协议解决了什么问题&#xff0c;在实际工作中有什么具体的意义&#xff0c;想到了这些我想你的技术会更有所提升&#xff0c;Tcp协议是程序员编程中的最重要的一块基石&#xff0c;Tcp是怎样进行可靠准确的传输数据…

web-ssrf

目录 ssrf介绍 以pikachu靶场为例 curl 访问外网链接 利用file协议查看本地文件 利用dict协议扫描内网主机开放端口 file_get_content 利用file协议查看本地文件&#xff1a; fsockopen() 防御方式: ssrf介绍 服务器端请求伪造&#xff0c;是一种由攻击者构造形成…

CSP复习每日一题(四)

树的重心 给定一颗树&#xff0c;树中包含 n n n 个结点&#xff08;编号 1 ∼ n 1∼n 1∼n&#xff09;和 n − 1 n−1 n−1条无向边。请你找到树的重心&#xff0c;并输出将重心删除后&#xff0c;剩余各个连通块中点数的最大值。 重心定义&#xff1a; 重心是指树中的一…

链式二叉树统计结点个数的方法和bug

方法一&#xff1a; 分治&#xff1a;分而治之 int BTreeSize1(BTNode* root) {if (root NULL) return 0;else return BTreeSize(root->left)BTreeSize(root->right)1; } 方法二&#xff1a; 遍历计数&#xff1a;设置一个计数器&#xff0c;对二叉树正常访问&#…

dubbo之高可用

负载均衡 概述 负载均衡是指在集群中&#xff0c;将多个数据请求分散到不同的单元上执行&#xff0c;主要是为了提高系统的容错能力和对数据的处理能力。 Dubbo 负载均衡机制是决定一次服务调用使用哪个提供者的服务。 策略 在Dubbo中提供了7中负载均衡策略&#xff0c;默…

冒泡排序 简单选择排序 插入排序 快速排序

bubblesort 两个for循环&#xff0c;从最右端开始一个一个逐渐有序 #include <stdio.h> #include <string.h> #include <stdlib.h>void bubble(int *arr, int len); int main(int argc, char *argv[]) {int arr[] {1, 2, 3, 4, 5, 6, 7};int len sizeof(…

想要延长Macbook寿命?这六个保养技巧你必须get!

Mac作为我们工作生活的伙伴&#xff0c;重要性不需要多说。但在使用的过程中&#xff0c;我们总会因不当操作导致Mac出现各种问题。 要想它长久的陪伴&#xff0c;平时的维护与保养自然不能少&#xff0c;Mac的保养很重要的两点就是硬件保养和电脑系统保养&#xff0c;硬件保养…

【一】初步认识数据库

数据库概览数据库 缘起表(Table)的理解用表来定义数据库数据库系统的理解概念层次的理解实例层次的理解 数据库管理系统的理解从用户角度看从系统实现角度看典型的数据库管理系统 数据库语言数据库定义、操纵、控制语言数据库语言 VS 高级语言 内容回顾练习 数据库概览 走马观…