跳到主要内容

怎么把chrome部署在远程服务器,并且通过selenium驱动?

1. 前言

本地使用selenium驱动谷歌浏览器的时候非常简单,只需要引入如下依赖就行。

也不用你下载浏览器驱动,因为依赖中会自动进行下载,而当你想把你写的这个自动化项目部署在远程服务器的时候,就不是这样处理了,因为服务器一般是GNU/Linux系统。

这篇文章会说明怎么在远程服务器使用selenium

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

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>4.18.1</version>
</dependency>

2. 使用docker部署Selenium Grid Server

Selenium 提供了能通过docker部署的Selenium Grid Server,简单说就是使用 Docker 在 Chrome、Firefox 和 Edge 中运行 Selenium Grid 的简单方法,使浏览器自动化的执行更加轻松。项目地址在这:https://github.com/SeleniumHQ/docker-selenium

2.1 如何使用呢?

在项目地址中也已经写明,通过如下命令进行拉取启动:

docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" selenium/standalone-firefox:4.19.0-20240328

对上面的命令进行解释:

  • -d:这是一个选项,表示在后台(守护进程)模式下运行容器。
  • p 4444:4444:这是一个选项,用于将容器内部的端口 4444 映射到主机的端口 4444。这是为了让主机能够通过该端口访问容器中运行的服务。
  • p 7900:7900:这是另一个选项,将容器内部的端口 7900 映射到主机的端口 7900。这可能是为了支持远程调试等特定用途。
  • -shm-size="2g":这是一个选项,设置容器内存中共享内存的大小为 2GB。共享内存用于容器内进程之间的通信和共享数据。
  • selenium/standalone-firefox:4.19.0-20240328:这是指定要运行的 Docker 镜像的名称和标签。在这种情况下,它是 Selenium Standalone Firefox 镜像的特定版本。

这里需要注意的是,上面命令使用的是firefox,而如果你想要选择的是chrome,你可以在docker hub中找到:https://hub.docker.com/u/selenium

那么运行的命令如下:

docker run -d -p 4444:4444 -p 7900:7900 \
-v /dir/selenium/data:/dir/selenium/data \
--shm-size="2g" selenium/standalone-chrome:122.0

注意: 我这里使用了-v 挂载了容器中的目录,是因为某些时候你需要保存浏览器的登录信息,这样你的代码中使用options.addArguments("--user-data-dir=/dir/selenium/data"); 可以指向到这个路径。

另外需要注意的是,如果你的是m1芯片的Mac,使用docker可以拉取镜像并且启动,但是通过代码连接后,会抛出浏览器崩溃的问题。

当你执行完命令,容器跑起来之后,你可以通过下面访问7900端口,以VNC的方式看到容器中发生了什么

http://ip:7900/?autoconnect=1&resize=scale&password=secret

界面如下:

3. 修改你的代码进行适配

既然浏览器已经被我们放在了远端,那么我们需要也需要增加新的依赖进行驱动远端浏览器才行。

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-remote-driver</artifactId>
<version>4.18.1</version>
</dependency>

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-api</artifactId>
<version>4.18.1</version>
</dependency>

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-http</artifactId>
<version>4.18.1</version>
</dependency>

上面三个依赖在测试中发现都是需要的加的,否则会抛出:ClassNotFound的问题。

而你的代码也从WebDriver driver = new ChromeDriver(options); 改为了

ChromeOptions options = new ChromeOptions();
options.addArguments("--user-data-dir=/dir/selenium/dat");
WebDriver driver = new RemoteWebDriver(new URL("http://ip:4444/wd/hub"), options);

其他的操作则和驱动本地浏览器的一样了,不需要修改代码。

另外,这并不是唯一的写法,在selenium的官方教程中,还可以这样,指定不同的浏览器类型:

ImmutableCapabilities capabilities = new ImmutableCapabilities("browserName", "chrome");
WebDriver driver = new RemoteWebDriver(new URL("http://ip:4444/wd/hub"), capabilities);