Cursor IDE 下 Docker Selenium 可复用工作流

多仓库共用 Compose / Tasks:RSelenium 1.7.9 现行与 CRAN selenium 迁移

Cursor
Docker
Selenium
RSelenium
Windows
工程化
Author

胡华平

Published

August 24, 2026

摘要

本文整理在 Cursor IDE 中,用 Docker Desktop + Compose +(可选)Docker 扩展 / Tasks,为各业务仓库提供可复制的 Selenium Chrome 浏览器自动化环境。经验来源于教学成绩仓库 Rexam 的实验提交抓取流程,抽象后供 harness 及任意业务仓库复用。

客户端分两条线,不要混用镜像与 R 包

客户端 Grid Compose 服务 说明
RSelenium 1.7.9(现行) Selenium 3 JSON Wire chrome-debug-legacy--profile debug-legacy 依赖已废弃的 standalone-chrome-debug;对 Selenium 4 的 standalone-chromeremDr$open() 常挂起
CRAN selenium(迁移方向) Selenium 4 W3C chromechrome-debug--profile debug 无头省内存;调试用同一镜像 + noVNC :17900

核心结论:

  1. 每个仓库可各自放置一份 docker-compose.selenium.yml同一标签的镜像全机共用。现行线与迁移线是两套镜像*-debugstandalone-chrome),磁盘上会各占一份。
  2. 同时只跑一个 映射主机 5555 的服务;用完即 down
  3. 调试时 勿映射主机 5901(Windows 常保留 5901–6000);新旧 debug 的传统 VNC 均用 15900:5900。仅 Selenium 4 debug 提供浏览器 noVNC :17900
  4. 可复制最小集 = 1 个 Compose 文件 + 对应客户端的 up / 就绪检查 / down;Cursor Task 为可选加速器。Windows 就绪检查用 curl.exe。Selenium 4 查 /status,RSelenium / Selenium 3 查 /wd/hub/status

1. 适用场景与非目标

1.1 适用

  • 学期末 / 偶发批次:登录校内或外部站点,抓取动态页面(iframe、点击、分页等)。
  • 希望减少手工:不再每次手敲 docker run、不再默认依赖 tvnViewer。
  • 多仓库(A / B / …)希望 同一套启动习惯,仅改项目名与端口策略。

1.2 非目标

  • 不替代合法登录与权限;账号密码仍用本机密钥环(如 R keyring),勿写入仓库。
  • 不保证某一具体站点选择器长期有效(DOM 改版需改业务脚本)。
  • 不以 Cursor 内置浏览器 / Browser MCP 作为批次爬虫主路径。

1.3 参考实现(来源)

工件 路径(Rexam 示例)
Compose record-workflow/docker-compose.selenium.yml
Cursor Tasks .vscode/tasks.json
流程说明 record-workflow/task-scrape-lab-submit.qmd
业务脚本 record-stat/code/03-lab-submit-01-scrape.R

本文给出的模板已 去业务化(项目名、路径改为占位符),可直接拷入其他仓库。


2. 架构总览

flowchart TB
  ide["Cursor IDE / 终端"]
  legacy["chrome-debug-legacy<br/>standalone-chrome-debug"]
  modern["chrome / chrome-debug<br/>standalone-chrome Selenium 4"]
  rs["RSelenium 1.7.9"]
  se["CRAN selenium"]
  ide -->|"profile debug-legacy"| legacy
  ide -->|"up chrome 或 profile debug"| modern
  legacy -->|"localhost:5555 /wd/hub"| rs
  modern -->|"localhost:5555"| se

2.1 演进对照

旧习惯 推荐习惯
启动 手敲 docker run,侧栏残留旧容器 Compose + 固定服务名
IDE 仅终端 Cursor Docker 扩展查看状态;Tasks 一键启停
可视化 默认 VNC 常映射 5901 新旧 debug 均用 15900;仅 Selenium 4 debug 另开 noVNC :17900
客户端 仅 RSelenium 1.7.9 + *-debug 镜像 现行仍走 debug-legacy新项目用 CRAN selenium + standalone-chrome
多仓库 命令不一致、易撞端口 统一模板;name / container_name 按项目区分

2.2 为何不要映射主机 5901

Windows(尤其 Hyper-V)常通过 excluded port range 保留 5901–6000。此时:

bind: An attempt was made to access a socket in a way forbidden by its access permissions

在 Cursor Docker 扩展里对旧容器点 Start 也会失败。处理:日常不映射 VNC;若需要,传统 VNC 用 15900:5900,浏览器 noVNC 用 17900:7900(或其它非保留端口),禁止 5901

自查保留区间(PowerShell / CMD):

netsh interface ipv4 show excludedportrange protocol=tcp

3. 磁盘与内存:多仓库会不会「堆满」容器?

3.1 结论(先看这个)

对象 是否因「每仓库一份 yml」而暴涨 说明
Compose / Tasks 文本 每份数 KB
镜像 standalone-chrome 否(通常一份) Selenium 4 线;多项目共用同一 image
镜像 standalone-chrome-debug 否(通常一份) RSelenium 1.7.9 线;已废弃但仍被 JSON Wire 客户端需要
容器 仅在你 up 之后存在 down 后可删除;残留可写层通常远小于镜像
正在运行的 Chrome 主要吃 RAM/CPU;内存紧时优先管这个

因此:可以为每个仓库都放 docker/docker-compose.selenium.yml,并设不同 name: project-B-selenium 磁盘压力来自「镜像版本堆积」和「从不清理的已停止容器」,不是 yml 份数。

3.2 推荐纪律(内存紧时)

  1. 同时只跑一个 Selenium(默认都用主机 5555 时也只能跑一个)。
  2. 用完:docker compose ... down --remove-orphans(或 Task Selenium: stop (remove containers))。确认真空闲再 --rmi all
  3. 偶尔清理:docker container prune;确认无用后再 docker image prune
  4. 必须两仓库并行时:第二套改 "5556:4444",客户端 port = 5556L

4. 可复制最小集

每个业务仓库建议落地:

<repo>/
  docker/
    docker-compose.selenium.yml    # 或放在 tools/、.devcontainer/ 旁,路径自定
  .vscode/
    tasks.json                     # 可选

把下文中的 projectb 换成短名(如 rexamharness-demo),保证:

  • Compose 顶层 name: 全局不撞车(影响默认网络名等);
  • container_name: 全局唯一(否则 docker 会拒绝或覆盖混乱)。

5. Compose 模板(拷贝即用)

权威副本scripts/docker-selenium/docker-compose.selenium.yml(资产索引:scripts/docker-selenium/index.qmd)。下文与之保持一致。将文件拷到业务仓库的 docker/docker-compose.selenium.yml 后,修改 namecontainer_name。也可用:

.\scripts\powershell\Install-Harness.ps1 -InstallProfile docker-selenium -ProjectRoot "D:\path\to\your-repo"
# 见 scripts/docker-selenium/docker-compose.selenium.yml 文件头注释
name: projectb-selenium

services:
  chrome:
    image: selenium/standalone-chrome:latest
    container_name: projectb-chrome
    shm_size: 2gb
    ports:
      - "5555:4444"
    environment:
      - SE_NODE_MAX_SESSIONS=1
      - SE_NODE_OVERRIDE_MAX_SESSIONS=true
      - SE_START_VNC=false
    restart: "no"

  chrome-debug:
    profiles: ["debug"]
    image: selenium/standalone-chrome:latest
    container_name: projectb-chrome-debug
    shm_size: 2gb
    ports:
      - "5555:4444"
      - "15900:5900"
      - "17900:7900"
    environment:
      - SE_NODE_MAX_SESSIONS=1
      - SE_NODE_OVERRIDE_MAX_SESSIONS=true
    restart: "no"

  chrome-debug-legacy:
    profiles: ["debug-legacy"]
    image: selenium/standalone-chrome-debug:latest
    container_name: projectb-chrome-debug-legacy
    shm_size: 2gb
    ports:
      - "5555:4444"
      - "15900:5900"
    restart: "no"

说明:

  • shm_size: 2gb:减轻 Chrome 在容器内因 /dev/shm 过小崩溃的概率。
  • chromechrome-debugchrome-debug-legacy 不要同时 up(都抢主机 5555)。
  • debug-legacy 仅供 RSelenium 1.7.9。镜像已废弃,新仓库不要把它当默认;需要可复现时可把标签钉成 3.141.59
  • Selenium 4 的 VNC/noVNC 已并入 standalone-chromedebug profile 面向 CRAN selenium
  • 无头 chromeSE_START_VNC=false 以省内存;教学仓库若要可复现,可将 Selenium 4 线的 :latest 换成官方发布标签(如 4.45.0-20260606)。

6. 标准操作指令

前置: Docker Desktop 状态为 Running

6.1 启动

RSelenium 1.7.9(现行):

docker compose -f docker/docker-compose.selenium.yml --profile debug-legacy up -d chrome-debug-legacy

CRAN selenium / Selenium 4 无头(迁移):

docker compose -f docker/docker-compose.selenium.yml up -d chrome

首次会拉镜像,可能较慢;之后复用本地镜像。RSelenium 请不要对 up -d chrome(Selenium 4)抱期望:remDr$open() 常会挂起。

6.2 就绪检查

启动后等待约 10–20 秒。

Selenium 4:

curl.exe http://127.0.0.1:5555/status

RSelenium / Selenium 3:

curl.exe http://127.0.0.1:5555/wd/hub/status

Windows PowerShell 中 curl 常是 Invoke-WebRequest 的别名,输出不是 curl 的 JSON;请显式调用 curl.exe

响应 JSON 中应含类似 "message": "Selenium Grid ready." 或旧版 status 字段。
亦可用浏览器打开对应 URL。

6.3 停止

日常(拆掉容器与默认网络,保留镜像,下次 up 不必重拉):

docker compose -f docker/docker-compose.selenium.yml --profile debug --profile debug-legacy down --remove-orphans

须带上 两个 profile,否则曾启动的 chrome-debugchrome-debug-legacy 可能残留。--remove-orphans 顺带清掉本项目里已不再定义的旧容器。

若学期结束、确定本机其它仓库也不再用 standalone-chrome / standalone-chrome-debug,可连镜像删除以腾磁盘(下次 up 会重新拉取约 1–2GB+):

docker compose -f docker/docker-compose.selenium.yml --profile debug --profile debug-legacy down --remove-orphans --rmi all

6.4(可选)Selenium 4 调试 + noVNC / VNC

docker compose -f docker/docker-compose.selenium.yml --profile debug up -d chrome-debug

优先用浏览器打开 http://127.0.0.1:17900/(noVNC)。也可让 VNC 客户端连接 localhost:15900。默认密码多为 secret。供 CRAN selenium 观察页面;日常批次可完全跳过。

6.5(可选)RSelenium 1.7.9 调试 + VNC

即 §6.1 的 debug-legacy。旧镜像没有 noVNC(无 7900)。VNC 客户端连接 localhost:15900(勿用 5901)。密码多为 secret

6.6 状态与日志

docker ps --filter name=projectb-chrome
docker logs --tail 50 projectb-chrome-debug-legacy

将过滤器换成你的 container_nameprojectb-chrome / projectb-chrome-debug / projectb-chrome-debug-legacy)。


7. Cursor IDE 集成

7.1 Docker 扩展

  • 侧栏 Containers 可查看/停止正在运行的容器。
  • 不要依赖「多年前 docker run 留下的旧容器」点 Start(易踩 5901 或过时端口)。
  • 当前仓库 Compose 起的容器(如 projectb-chrome)为准。

7.2 Tasks 模板(可选)

保存为 .vscode/tasks.json(若已有 tasks,合并进 tasks 数组即可)。权威副本:scripts/docker-selenium/vscode-tasks-selenium.jsonInstall-Harness -InstallProfile docker-selenium 会写成 .vscode/tasks-selenium.json(不覆盖已有 tasks.json)。

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Selenium: start (headless, Selenium 4 / CRAN selenium)",
      "type": "shell",
      "command": "docker compose -f docker/docker-compose.selenium.yml up -d chrome",
      "options": { "cwd": "${workspaceFolder}" },
      "problemMatcher": [],
      "presentation": { "reveal": "always", "panel": "shared" }
    },
    {
      "label": "Selenium: start (debug Selenium 4 + VNC :15900 / noVNC :17900)",
      "type": "shell",
      "command": "docker compose -f docker/docker-compose.selenium.yml --profile debug up -d chrome-debug",
      "options": { "cwd": "${workspaceFolder}" },
      "problemMatcher": [],
      "presentation": { "reveal": "always", "panel": "shared" }
    },
    {
      "label": "Selenium: start (legacy debug for RSelenium 1.7.9)",
      "type": "shell",
      "command": "docker compose -f docker/docker-compose.selenium.yml --profile debug-legacy up -d chrome-debug-legacy",
      "options": { "cwd": "${workspaceFolder}" },
      "problemMatcher": [],
      "presentation": { "reveal": "always", "panel": "shared" }
    },
    {
      "label": "Selenium: stop (remove containers)",
      "type": "shell",
      "command": "docker compose -f docker/docker-compose.selenium.yml --profile debug --profile debug-legacy down --remove-orphans",
      "options": { "cwd": "${workspaceFolder}" },
      "problemMatcher": [],
      "presentation": { "reveal": "always", "panel": "shared" }
    },
    {
      "label": "Selenium: stop and remove images",
      "type": "shell",
      "command": "docker compose -f docker/docker-compose.selenium.yml --profile debug --profile debug-legacy down --remove-orphans --rmi all",
      "options": { "cwd": "${workspaceFolder}" },
      "problemMatcher": [],
      "presentation": { "reveal": "always", "panel": "shared" }
    },
    {
      "label": "Selenium: status",
      "type": "shell",
      "command": "docker compose -f docker/docker-compose.selenium.yml --profile debug --profile debug-legacy ps; curl.exe http://127.0.0.1:5555/status; curl.exe http://127.0.0.1:5555/wd/hub/status",
      "options": { "cwd": "${workspaceFolder}" },
      "problemMatcher": [],
      "presentation": { "reveal": "always", "panel": "shared" }
    }
  ]
}

使用:Ctrl+Shift+PTasks: Run Task → 选择对应项。

路径若不是 docker/docker-compose.selenium.yml,改 Task 与文档中的 -f 即可。


8. 客户端连接

端口均为主机 5555。先按 §6 启动匹配的 Grid,再开客户端。

8.1 现行:RSelenium 1.7.9

对应 --profile debug-legacy。默认会话路径为 /wd/hub

library(RSelenium)

remDr <- remoteDriver(
  remoteServerAddr = "localhost",
  port = 5555L,
  browserName = "chrome"
)
remDr$open()
remDr$maxWindowSize()

# ... 业务操作 ...

remDr$close()
rm(remDr)
gc()

open() 挂起且 Grid 是 standalone-chrome(无 -debug),改用 chrome-debug-legacy,不要改 R 代码去「适配」Selenium 4。

8.2 迁移方向:CRAN selenium

对应 up -d chrome--profile debug。包文档:https://cran.r-project.org/package=selenium

library(selenium)

session <- SeleniumSession$new(
  browser = "chrome",
  host = "localhost",
  port = 5555L
)

# ... 业务操作,例如 session$navigate("https://example.com") ...

session$close()

凭证建议:

# 一次性设置(示例)
# keyring::keyring_create("lab")
# keyring::key_set("usr", keyring = "lab")
# keyring::key_set("password", keyring = "lab")
# keyring::key_get("usr", keyring = "lab")

勿将密码写入 git。其他语言(Python selenium、Playwright 连已有 Grid 等)在 Selenium 4 线上同样指向 http://localhost:5555


9. 多仓库落地检查清单

复制到新仓库 Project B 时按序勾选:

  1. [ ](可选)拷贝/合并 .vscode/tasks.json

10. 故障排查

现象 可能原因 处理
扩展 Start 旧容器失败,含 access permissions 主机端口落在 Windows 保留段(如 5901) 弃用旧容器;用本文 Compose;VNC 改 15900,noVNC 用 17900
curl 返回 HTML / 方法对象而非 JSON PowerShell 把 curl 当成 Invoke-WebRequest 改用 curl.exe
remDr$open() 失败 / 挂起 / $idNA 把 Selenium 4 standalone-chrome 配给了 RSelenium 1.7.9 改用 --profile debug-legacy;就绪查 /wd/hub/status
remDr$open() 连接重置 容器未就绪或未启动 等 15s;查对应 status URL;看 docker logs
CRAN selenium 连不上 仍跑着 legacy debug 容器 downup -d chrome--profile debug
port is already allocated 另一套 Selenium 仍占用 5555 docker psdown,或换 5556
Chrome 容器内崩溃 /dev/shm 过小 保持 shm_size: 2gb
镜像拉取很慢/失败 网络 配置镜像加速或稍后重试;与代理文档(harness 内 v2ray 指南)配合
登录/选择器失败 站点改版或验证码 属业务层;RSelenium 用 VNC :15900;新线用 noVNC :17900

11. 在 harness 中的位置

本文档路径:

harness/docs/cursor-docker-selenium-workflow.qmd

可单独拷贝的资产(canonical):

harness/scripts/docker-selenium/docker-compose.selenium.yml
harness/scripts/docker-selenium/vscode-tasks-selenium.json
harness/scripts/docker-selenium/index.qmd

业务仓库(如 Rexam)建议保留 指向本文的链接 + 本仓库实际使用的 Compose(可含项目专用 name),避免两处长文双轨失同步。

版本约定: 本文 YAML 中 version / date 随修订递增;重大变更(默认端口、镜像标签策略)在摘要下追加简短 changelog。

Changelog

版本 日期 说明
1.3.1 2026-08-24 补全 down --remove-orphans;可选 --rmi all 删除本 compose 用过的镜像
1.3.0 2026-08-24 增加 debug-legacystandalone-chrome-debug)供 RSelenium 1.7.9;debug 保留给 Selenium 4 / CRAN selenium
1.2.0 2026-08-24 资产从 templates/docker-selenium/ 迁到 scripts/docker-selenium/;增加 Install-Harness profile docker-selenium
1.1.0 2026-08-24 去掉已废弃的 standalone-chrome-debug;debug 改用同一镜像 + noVNC :17900;Windows 就绪检查改 curl.exe;架构图改为 Quarto {mermaid}
1.0.0 2026-08-24 初版:从 Rexam 实验抓取工作流抽象为多仓库可复制指南

12. 一页速查(可打印)

# 0. Docker Desktop = Running
# A. 现行 RSelenium 1.7.9
docker compose -f docker/docker-compose.selenium.yml --profile debug-legacy up -d chrome-debug-legacy
curl.exe http://127.0.0.1:5555/wd/hub/status
# R: remoteDriver(..., port = 5555L); remDr$open()

# B. 迁移:CRAN selenium + Selenium 4
docker compose -f docker/docker-compose.selenium.yml up -d chrome
curl.exe http://127.0.0.1:5555/status
# R: selenium::SeleniumSession$new(browser="chrome", host="localhost", port=5555L)

# 调试(Selenium 4): --profile debug up -d chrome-debug
#   浏览器: http://127.0.0.1:17900/    VNC: localhost:15900
# 停止(两个 profile + 孤儿容器):
docker compose -f docker/docker-compose.selenium.yml --profile debug --profile debug-legacy down --remove-orphans
# 连镜像删除(腾磁盘;其它项目若还用这两份 image 则不要执行):
# docker compose -f docker/docker-compose.selenium.yml --profile debug --profile debug-legacy down --remove-orphans --rmi all

# 规则:勿用主机 5901;5555 上同时只跑一个服务;yml 可多仓复制。