本文介绍使用Selenium驱动操作无头浏览器截取屏幕,使用的是selenium-java SDK
Selenium 是一套用于自动化 Web 浏览器的工具。是 thoughtworks 公司的一个集成测试的强大工具。
主流搭建selenium环境有两种手段
可以直接采用SpringBoot导入对应SDK结合selenium driver操作对应的brower,也可以将某个链接丢入selenium server进行截取。下面分别介绍两种方式。
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
<exclusions>
<exclusion>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>3.2.0</version>
</dependency>
ChromeOptions options = new ChromeOptions();
//ssl证书支持
options.setCapability("acceptSslCerts", true);
//截屏支持
options.setCapability("takesScreenshot", true);
//css搜索支持
options.setCapability("cssSelectorsEnabled", true);
//无界面
options.addArguments("--headless");
options.addArguments("--remote-allow-origins=*");
options.addArguments("--no-sandbox");
options.addArguments("--disable-gpu");
options.addArguments("--disable-dev-shm-usage");
options.setHeadless(true);
ChromeDriver driver = new ChromeDriver(options);
//设置超时,避免有些内容加载过慢导致截不到图
driver.manage().timeouts().pageLoadTimeout(Duration.ofMinutes(2));
driver.manage().timeouts().implicitlyWait(Duration.ofMinutes(2));
driver.manage().timeouts().scriptTimeout(Duration.ofMinutes(2));
//快照文件
driver.get(url);
driver.manage().window().setSize(new Dimension(1920, 1080));
log.info("----等待60秒报表界面加载完毕------");
Thread.sleep(60000);
log.info("开始截屏");
log.info("当前页面标题:" + driver.getTitle());
#截取后的文件,可以重命名为图片格式
File file = driver.getScreenshotAs(OutputType.FILE);
引入selenium driver来操作对应的浏览器
下载地址:谷歌驱动
按对应的浏览器版本驱动进行下载
在main启动的地方设置驱动的位置
# window
System.getProperties().setProperty("webdriver.chrome.driver", "D:\\Download\\chromedriver_win32\\chromedriver.exe");
此种方式需要注意如果你linux环境或容器运行,那么需要你的机器/容器基础镜像也需要安装对应的浏览器。
优势:selenium和springboot结合成一起方便使用。
劣势:会和springboot进行捆绑使用,内存占用比较大,会影响附带的业务。
自搭selenium服务端
自搭selenium 客户端服务器一体化镜像
selenium官方的镜像hub地址
docker run -d -p 12121:4444 -p 12122:7900 --shm-size="2g" -e SE_NODE_MAX_SESSIONS=10 selenium/standalone-chrome:latest
其中4444端口用于截取屏幕的端口,7900用于远程VNC使用的端口,SE_NODE_MAX_SESSIONS表示最大的session数量
然后你得到了一个selenium server的ip+port端口
假设为:192.168.0.110:121:12121
接下来开始
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
<exclusions>
<exclusion>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>3.2.0</version>
</dependency>
DesiredCapabilities capabilities = new DesiredCapabilities("chrome", "120.0", Platform.LINUX);
# 其中serverIp 为上面selenium-server的IP:Port
RemoteWebDriver driver = new RemoteWebDriver(new URL(serverIp + "/wd/hub"), capabilities);
//设置超时,避免有些内容加载过慢导致截不到图
driver.manage().timeouts().pageLoadTimeout(Duration.ofMinutes(2));
driver.manage().timeouts().implicitlyWait(Duration.ofMinutes(2));
driver.manage().timeouts().scriptTimeout(Duration.ofMinutes(2));
//设置需要访问的地址
driver.get("要截取的快照url地址");
driver.manage().window().setSize(new Dimension(1920, 1080));
log.info("----等待60秒报表界面加载完毕------");
Thread.sleep(60000);
log.info("开始截屏");
log.info("当前页面标题:" + driver.getTitle());
#截取后的文件,可以重命名为图片格式
File srcFile = driver.getScreenshotAs(OutputType.FILE);
优势:方便更新selenium的版本,不会和springboot应用绑定,因为是连接服务端截取的文件所以不需要基础镜像带浏览器等组件,且selenium官方也针对组件进行了优化;比如防爬虫处理。只需要把serverIp的参数放到配置中。
使用RemoteWebDriver,可以在本地机器上编写测试脚本,然后将测试请求发送到远程机器上的浏览器中执行。这使得测试可以在多个不同的机器上并行运行,从而加快测试的执行速度。
劣势:需要准备一个单独部署selenium server。
要使用RemoteWebDriver,需要启动一个Selenium?Server,
当执行请求时,selenium服务器会收到一条消息用户执行具体逻辑
架构图
selenium驱动与谷歌浏览器版本对照
https://googlechromelabs.github.io/chrome-for-testing/