JAVA 程序访问无头浏览器做爬虫等(兼容 docker 环境)

什么是无头浏览器(Headless)

无头浏览器可以在图形界面中或者是纯命令行的方式运行的浏览器,可以通过程序控制浏览器执行任务,可以做网页测试、网页截图、录屏、爬虫等。如果你想获取一些浏览器端渲染 (CSR) 的网站,常规的 get 请求返回网页文件的方式往往无法获取到渲染后的数据,这时候就需要使用无头浏览器。

本文主要涉及技术栈

Java Headless Selenium Spring Docker Maven Linux

安装 chrome 以及驱动程序

首先需要运行环境中有 chrome ,对图形化系统来说官方下载的 chrome 即可。 非图形化系统需要手动安装 chrome

如果你想在 docker 中运行,忽略安装步骤,请直接拉到最下面

centos 下安装

sudo vi /etc/yum.repos.d/google.repo

google.repo 写入

[google]
name=Google-x86_64
baseurl=http://dl.google.com/linux/rpm/stable/x86_64
enabled=1
gpgcheck=0
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub

运行安装程序

sudo yum install google-chrome-stable

检查安装版本

google-chrome --version

驱动下载

首先确认运行环境 chrome 版本是多少,前往 chrome driver 下载对应版本,对应系统的驱动。

Java 中控制无头浏览器

maven

<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-java</artifactId>
</dependency>

简简单单获取一个网页标题 当然你也可以参考 selenium 使用更多的能力,这里就不在细说

public String getUrlTitleName(String url) {
    // 你驱动下载到的位置
    String CHROME_DRIVER = "/usr/local/chromeDriver/";
    WebDriver driver;
    try {
        // 当前运行环境中所要加载的驱动
        File driverFile;
        if (SystemUtils.IS_OS_LINUX) {
            // 名称按照你的驱动名称来
            driverFile = new File(CHROME_DRIVER + "chromedriver_linux_96_0_4664");
        } else if (SystemUtils.IS_OS_MAC) {
            driverFile = new File(CHROME_DRIVER + "chromedriver_mac_96_0_4664");
        } else {
            throw new BusinessException("无法在非 Mac Linux 系统下运行!!!");
        }
        try {
            ChromeDriverService.Builder builder = new ChromeDriverService.Builder();
            builder.usingDriverExecutable(driverFile);
            ChromeDriverService build = builder.build();
            ChromeOptions chromeOptions = new ChromeOptions();
            // 无头浏览器参数配置
            chromeOptions.addArguments("-headless", "--disable-gpu", "window-size=1024,768", "--no-sandbox");
            driver = new ChromeDriver(build, chromeOptions);
        } catch (Exception e) {
            log.error("无法启动 WebDriver", e);
            throw new BusinessException("\n " +
                    "无法启动主程序! 请检查宿主机 chrome 版本! \n" +
                    "支持版本为 96.0.4664 \n" +
                    "如版本不一致, 请调整 chromedriver 或宿主机 chrome 版本!");
        }
        // 访问 url
        driver.get(url);
        // 获取网页标题
        return driver.getTitle();
    } catch (Exception e) {
        throw new BusinessException("无头浏览器访问页面失败", e);
    } finally {
        if (Objects.nonNull(driver)) {
            // 执行完一定要关闭
            driver.quit();
        }
    }
}

Docker / k8s 中运行此 Java 程序

踩了很多很多坑,终于让我找到一个可以正常运转的镜像了 standalone-chrome

构建 docker 镜像

此处以 chrome 96.0.4664 为例 其中 jdk 安装包、chromeDriver 驱动文件夹需要提前准备好、app.jar 为你的 java 服务

FROM selenium/standalone-chrome:96.0.4664.110-chromedriver-96.0.4664.45
ADD jdk-8u341-linux-x64.tar.gz /usr/local/java
COPY chromeDriver /usr/local/chromeDriver
ENV JAVA_HOME=/usr/local/java/jdk1.8.0_341
ENV PATH=$PATH:$JAVA_HOME/bin
COPY app.jar /
ENTRYPOINT ["java", "-jar", "/app.jar"]

可直接下载我这份压缩包,里面有所需要准备好的驱动以及 JDK 归档 image

消息盒子

# 暂无消息 #

只显示最新10条未读和已读信息