【Chrome】使用k8s、docker部署无头浏览器Headless,Java调用示例

什么是无头浏览器?

无头浏览器是一种没有图形用户界面的浏览器。无头浏览器不通过其图形用户界面(GUI)控制浏览器的操作,而是使用命令行。

为什么要用Chrome无头?

  • Chrome Headless用于抓取(谷歌)、测试(开发者)和黑客(黑客)。
  • 搜索引擎,使用它来呈现页面、生成动态内容和索引来自单页Web应用程序的数据。
  • SEO工具,用来分析网站,提出如何改进的建议。
  • 监控工具,用于监控Web应用中JavaScript的执行时间。
  • 一个测试工具,用于呈现页面并将其与以前的版本进行比较,以跟踪用户界面的变化。
  • 使用Headless Chrome的主要优势在于,用户可以编写脚本以编程方式运行浏览器,并快速、大规模地执行抓取、分析或成像网站等任务,而无需打开浏览器的GUI并点击一百万个东西。
  • 要做到这一点需要三样东西:无头ChromeDevTools协议和木偶师。
  • 你已经见过Chrome Headless了。Dev ProtocolChrome DevTools的远程实例,在另一个浏览器中打开。它允许你"通过你的眼睛"看到无头Chrome,而不需要运行浏览器GUIPuppeteer是一个节点库,它为开发者提供了通过DevTools协议编程控制无头Chrome的工具。
  • 把三者结合起来,就可以用Headless Chrome编写重复的大规模动作脚本,并快速大规模运行。

安装chrome浏览器并测试

基本上每个程序员都会安装chrome浏览器,如果没有安装的可以去下载安装,安装好之后,可以直接利用chrome浏览器执行无头浏览器的命令,假设chrome浏览器安装路径是: C:\Users\administrator\AppData\Local\Google\Chrome\Application\chrome.exe,可以执行如下命令

shell 复制代码
C:\Users\best5\AppData\Local\Google\Chrome\Application\chrome.exe --headless --hide-scrollbars --disable-gpu --screenshot=e:\chrome.jpg  --window-size=1280,1696 https://www.baidu.com

会生成一个chrome.jpg文件

Docker运行

  • 拉取镜像: docker pull browserless/chrome:latest
  • 运行容器: docker run -p 3000:3000 browserless/chrome:latest
  • 使用浏览器访问: http://localhost:3000/

看起来很厉害的样子

k8s部署

  • 编写部署ymal文件,并命名browserless-chrome.yaml
yaml 复制代码
---
apiVersion: v1
kind: Service
metadata:
  name: browserless-chrome
  namespace: kube-public
  labels:
    app: browserless-chrome
spec:
  type: NodePort
  ports:
    - name: websocket
      port: 30000
      targetPort: 3000
      nodePort: 30000
  selector:
    app: browserless-chrome
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: browserless-chrome
  namespace: kube-public
spec:
  replicas: 1
  revisionHistoryLimit: 0 #Replica Sets中的历史数量
  selector:
    matchLabels:
      app: browserless-chrome
  template:
    metadata:
      labels:
        app: browserless-chrome
    spec:
      containers:
        - name: browserless-chrome
          imagePullPolicy: Always
          image: browserless/chrome:latest
          env:
            - name: PORT
              value: "3000"
          securityContext:
            runAsNonRoot: true
            runAsUser: 999
            runAsGroup: 999
          ports:
            - containerPort: 3000
          livenessProbe:
            tcpSocket:
              port: 3000
            initialDelaySeconds: 5
            failureThreshold: 2
            periodSeconds: 60
          readinessProbe:
            tcpSocket:
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 10
          startupProbe:
            tcpSocket:
              port: 3000
            failureThreshold: 30
            periodSeconds: 10
          resources:
            requests:
              cpu: 0.2
              memory: 300Mi
            limits:
              cpu: 1
              memory: 1Gi
      imagePullSecrets:
        - name: puller
  • kubectl apply -f browserless-chrome.yaml

把镜像推送到私有仓库

  • 给镜像重新打标签: docker tag browserless/chrome:latest xxx.cn/base/browserless-chrome:latest
  • 推送到私有仓库: docker push imgsreg.ipipa.cn:20443/base/browserless-chrome:latest

Java调用示例

  • pom.xml中添加以下依赖
xml 复制代码
<dependency>
  <groupId>io.github.fanyong920</groupId>
  <artifactId>jvppeteer</artifactId>
  <version>1.1.5</version>
</dependency>
  • 使用本地chrome程序调用示例代码
java 复制代码
public class BrowserTest {

    @SneakyThrows
    @Test
    void test() {
        //自动下载,第一次下载后不会再下载
//        BrowserFetcher.downloadIfNotExist(null);
        ArrayList<String> arrayList = new ArrayList<>();
        //生成pdf必须在无头模式下才能生效
        LaunchOptions options = new LaunchOptionsBuilder()
                .withExecutablePath("C:\\Users\\administrator\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe")
                .withArgs(arrayList)
                .withHeadless(true)
                .build();
        arrayList.add("--no-sandbox");
        arrayList.add("--disable-setuid-sandbox");
        Browser browser = Puppeteer.launch(options);
        Page page = browser.newPage();
        page.goTo("https://www.baidu.com");
        PDFOptions pdfOptions = new PDFOptions();
        pdfOptions.setPath("test.pdf");
        page.pdf(pdfOptions);
        page.close();
        browser.close();
    }
}
  • 使用wetsocket远程调用chrome示例代码
java 复制代码
public class BrowserTest {

    @SneakyThrows
    @Test
    void test() {
        //自动下载,第一次下载后不会再下载
//        BrowserFetcher.downloadIfNotExist(null);
        ArrayList<String> arrayList = new ArrayList<>();
        //生成pdf必须在无头模式下才能生效
        LaunchOptions options = new LaunchOptionsBuilder()
                .withArgs(arrayList)
                .withHeadless(true)
                .build();
        arrayList.add("--no-sandbox");
        arrayList.add("--disable-setuid-sandbox");
        Browser browser = Puppeteer.connect(options, "ws://localhost:3000", null, null);
        Page page = browser.newPage();
        page.goTo("https://www.baidu.com");
        PDFOptions pdfOptions = new PDFOptions();
        pdfOptions.setPath("test.pdf");
        page.pdf(pdfOptions);
        page.close();
        browser.close();
    }
}

在工程目录下会生成test.pdf文件,可以打开看看效果

相关推荐
火星数据-Tina9 小时前
体彩数据API
前端·websocket
薛纪克9 小时前
Lambda Query:让微软Dataverse查询像“说话”一样简单
java·spring·microsoft·lambda·dataverse
程序员-周李斌9 小时前
CopyOnWriteArrayList 源码分析
java·开发语言·哈希算法·散列表
廋到被风吹走9 小时前
【Spring】两大核心基石 IoC和 AOP
java·spring
明有所思9 小时前
springsecurity更换加密方式
java·spring
victory04319 小时前
K8S etcd 数据存储路径迁移
容器·kubernetes·etcd
却话巴山夜雨时i9 小时前
295. 数据流的中位数【困难】
java·服务器·前端
洛克大航海9 小时前
Ubuntu 安装 Docker
linux·docker·ubuntu24.04
java干货9 小时前
优雅停机!Spring Boot 应用如何使用 Hook 线程完成“身后事”?
java·spring boot·后端