我有一个程序,通过使用selenium驱动程序在IE中打开所需的URL。但是我想在URL加载后关闭驱动程序exe。
我使用driver.quit();
导致清理exe并关闭浏览器。但是,我不想关闭已打开的浏览器
有没有办法在不使用的情况下实现这一目标
Runtime.getRuntime().exec("taskkill /F /IM IEDriverServer.exe");
?
答案 0 :(得分:2)
Helium会自动为您执行此操作 - 如果您在JVM终止时未调用driver.quit();
,则Helium会打开浏览器窗口但会清除驱动程序exe。
以下是实现的工作原理:Selenium类DriverService
管理driver.exe进程。我们需要操纵正确的DriverService
实例的字段来关闭exe。默认情况下无法访问这些字段,因此我们需要使用Java反射来访问它们。
首先,在启动IE时,您需要手动传入DriverService
实例:
InternetExplorerDriverService.Builder serviceBuilder = new InternetExplorerDriverService.Builder().usingAnyFreePort();
InternetExplorerDriverService service = serviceBuilder.build();
WebDriver ie = new InternetExplorerDriver(service);
// Open your URL:
ie.get("http://www.google.com");
要杀死驱动程序exe,首先需要获取服务的lock
字段。它不公开所以我们需要使用反射来访问它:
Field lockField = DriverService.class.getDeclaredField("lock");
lockField.setAccessible(true);
ReentrantLock lock = (ReentrantLock) lockField.get(service);
lock
用于防止对驱动程序exe的并发访问。要安全地访问驱动程序exe,我们需要将其余代码包装在try ... finally
块中:
try {
lock.lock();
[...]
} finally {
lock.unlock();
}
现在针对[...]
:我们需要通过反思再次访问process
字段:
Field processField = DriverService.class.getDeclaredField("process");
processField.setAccessible(true);
CommandLine process = (CommandLine) processField.get(service);
process
null
可能会发生,在这种情况下,我们无法做任何事情:
if (process == null)
return;
否则,我们调用process.destroy()
- 这会杀死驱动程序exe进程:
process.destroy();
...并将process
设置为null
:
processField.set(service, null);
就是这样!这是Helium的startIE(...)
命令背后发生的一些事情。