什么是无头浏览器(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 归档