RSelenium 使用 rsDriver() 时出现 open.connection 错误
结论
rsDriver() 启动 Chrome 时访问 PhantomJS,不代表它会用 PhantomJS 渲染页面。RSelenium 通过 wdman 管理 Selenium 和多个浏览器驱动,旧版初始化流程可能会同时检查 PhantomJS 的可用版本。如今,PhantomJS 的 Bitbucket 下载接口已无法正常访问,并返回 402 Payment Required,导致初始化在 Chrome 启动前中断。
如果只使用 Chrome,最直接的解决办法是关闭 PhantomJS 检查:
remote_driver <- rsDriver(
browser = "chrome",
chromever = "114.0.5735.90",
phantomver = NULL,
verbose = FALSE,
port = free_port()
)
为什么会访问 PhantomJS
rsDriver() 是一个便捷封装。除了创建 remoteDriver,它还会调用 wdman 检查或下载以下组件:
- Selenium Server
- ChromeDriver
- GeckoDriver
- PhantomJS
- 其他已配置的驱动组件
在某些版本中,phantomver 的默认值不是 NULL。因此,即使已经指定:
browser = "chrome"
驱动管理流程仍可能查询 PhantomJS 的版本列表。报错中的地址:
https://api.bitbucket.org/2.0/repositories/ariya/phantomjs/downloads?pagelen=100
就是旧版 wdman/binman 获取 PhantomJS 下载信息时使用的接口。
所以,这个错误通常与以下内容无关:
- Chrome 页面本身
- 抓取目标网站
rvestrJavafree_port()- 本机文件权限
出错的是 PhantomJS 下载列表查询。
推荐解决方法
1. 禁用不需要的驱动检查
如果只使用 Chrome,可以关闭其他浏览器驱动的版本检查:
library(RSelenium)
library(netstat)
remote_driver <- rsDriver(
browser = "chrome",
chromever = "114.0.5735.90",
geckover = NULL,
iedrver = NULL,
phantomver = NULL,
verbose = FALSE,
port = free_port()
)
remDr <- remote_driver$client
其中最重要的是:
phantomver = NULL
2. 更新相关 R 包
如果安装的版本较旧,可以更新 RSelenium、wdman 和 binman:
install.packages(c("RSelenium", "wdman", "binman"))
更新后重启 R 会话,再运行:
remote_driver <- rsDriver(
browser = "chrome",
chromever = "114.0.5735.90",
phantomver = NULL,
verbose = FALSE,
port = free_port()
)
更新后是否还会出现这一行为,取决于实际安装的包版本。即使完成更新,也建议保留 phantomver = NULL。
3. 已缓存所需组件时关闭版本检查
如果 Selenium Server 和 ChromeDriver 已下载到本机缓存,可以尝试:
remote_driver <- rsDriver(
browser = "chrome",
chromever = "114.0.5735.90",
phantomver = NULL,
check = FALSE,
verbose = FALSE,
port = free_port()
)
check = FALSE 可能会跳过远程版本检查,但前提是本地已有可用组件。如果缓存缺失或驱动版本不兼容,Selenium 仍无法启动。
ChromeDriver 版本也需要匹配
解决 PhantomJS 的 402 错误后,还需要确认 ChromeDriver 与本机 Chrome 兼容。当前代码固定使用:
chromever = "114.0.5735.90"
这个版本只适用于相应版本的 Chrome。如果浏览器已经自动升级,接下来可能会出现类似错误:
session not created: This version of ChromeDriver only supports Chrome version 114
可以先查看 Chrome 的实际版本,再指定兼容的 ChromeDriver。如果所用的 wdman 版本支持,也可以尝试:
remote_driver <- rsDriver(
browser = "chrome",
chromever = "latest",
phantomver = NULL,
verbose = FALSE,
port = free_port()
)
不过,旧版 wdman 对新版 ChromeDriver 下载机制的支持可能有限,latest 不一定能在所有旧环境中正确解析。
更稳定的替代方案
如果 rsDriver() 的自动下载机制一直失败,可以自行启动 Selenium Server,例如使用 Docker,再通过 remoteDriver() 连接。这样可以绕过 wdman 的 PhantomJS 检查:
docker run -d \
--name selenium-chrome \
-p 4444:4444 \
--shm-size="2g" \
selenium/standalone-chrome
在 R 中连接:
library(RSelenium)
remDr <- remoteDriver(
remoteServerAddr = "localhost",
port = 4444L,
browserName = "chrome"
)
remDr$open()
注意事项
HTTP status was '402 Payment Required'是 Bitbucket 接口返回的远程 HTTP 状态,并不是要求为RSelenium付费。- 反复重试或更换端口通常无效,因为错误发生在驱动下载检查阶段。
- PhantomJS 已停止维护。只使用 Chrome 时,应将
phantomver设置为NULL。 - 如果禁用 PhantomJS 后出现新的 ChromeDriver 错误,说明原来的
402已经被绕过,接下来需要检查 Chrome 与 ChromeDriver 的版本兼容性。 - 对于长期运行的抓取任务,更适合固定 Selenium/Chrome 镜像版本,以免浏览器自动升级后与驱动失配。
备注:内容仅供参考。
