并行运行两个Selenium RemoteWebDriver实例时操作同一Chrome窗口问题求助
Selenium Grid并行运行RemoteWebDriver实例串窗口问题
问题描述
尝试用Selenium Standalone/Grid并行运行两个RemoteWebDriver实例,同时操作不同窗口/网站。系统已创建两个会话和窗口,但第二个驱动实例却在第一个驱动实例的窗口上执行操作。
已尝试操作
启动Selenium Standalone的Docker命令
docker run -p 4444:4444 -p 7900:7900 --shm-size="2g" -e SE_NODE_GRID_URL="http://localhost:4444" -e SE_NODE_MAX_SESSIONS=5 -e SE_NODE_OVERRIDE_MAX_SESSIONS=true -e SE_VNC_NO_PASSWORD=1 selenium/standalone-chrome:4.16.1-20231212
Kotlin代码
ChromeOptions配置
private fun chromeOptions( profileName: String ): ChromeOptions { return ChromeOptions().apply { setCapability(ChromeOptions.CAPABILITY, this) addArguments("--allow-insecure-localhost") addArguments("--crash-dumps-dir=/tmp") addArguments("--remote-debugging-port=9222") addArguments("--user-data-dir=/tmp/chrome") addArguments("--profile-directory=$profileName") } }
爬取逻辑
suspend fun crawl() { val driverBBC = RemoteWebDriver( URL("http://localhost:4444/wd/hub"), chromeOptions("first") ) val driverNYT = RemoteWebDriver( URL("http://localhost:4444/wd/hub"), chromeOptions("second") ) try { driverBBC.manage().window().maximize() driverBBC.get("https://www.bbc.com/") println("bbc title: ${driverBBC.title}") delay(5000) driverNYT.manage().window().maximize() driverNYT.get("https://www.nytimes.com/") println("bbc title: ${driverBBC.title}") println("nyt title: ${driverNYT.title}") // 延迟后关闭 delay(60000) } catch (e: Exception) { logger.error("error while scraping", e) } finally { driverBBC.quit() driverNYT.quit() } }
预期结果
bbc title: BBC - Homepage bbc title: BBC - Homepage nyt title: The New York Times - Breaking News, US News, World News and Videos
实际结果
bbc title: BBC - Homepage bbc title: The New York Times - Breaking News, US News, World News and Videos nyt title: The New York Times - Breaking News, US News, World News and Videos
问题原因及解决方案
问题根源
- 固定远程调试端口冲突:两个实例都指定
--remote-debugging-port=9222,后启动的浏览器实例会覆盖前一个的调试连接,导致操作串到同一个窗口。 - 共享用户数据目录:所有会话使用同一个
--user-data-dir=/tmp/chrome,即使指定不同profile,也可能出现会话状态互相干扰的情况。 - 冗余配置:
setCapability(ChromeOptions.CAPABILITY, this)属于无效配置,ChromeOptions本身就是Capabilities实例,无需重复设置。
修正后的ChromeOptions代码
import java.util.UUID private fun chromeOptions( profileName: String ): ChromeOptions { return ChromeOptions().apply { addArguments("--allow-insecure-localhost") addArguments("--crash-dumps-dir=/tmp") // 移除固定远程调试端口,由Selenium自动分配 // addArguments("--remote-debugging-port=9222") // 为每个会话生成唯一的用户数据目录,彻底隔离环境 addArguments("--user-data-dir=/tmp/chrome-${UUID.randomUUID()}") addArguments("--profile-directory=$profileName") } }
说明
- 移除固定远程调试端口后,Selenium会为每个会话自动分配独立端口,避免冲突。
- 使用UUID生成唯一用户数据目录路径,确保每个会话的浏览器环境完全隔离,不会互相干扰。
内容的提问来源于stack exchange,提问作者qwerew
相关产品推荐
相关产品推荐

