mcpField
U
using-webctl

using-webctl

github.com/oaustegard开发15744 次安装1 天前更新
代码仓库

关于 using-webctl

用于在 Claude.ai 容器中通过 webctl 命令行进行浏览器自动化的技能,说明 Chromium 的认证代理解决方案,以及网页导航、检查和交互命令。

主要功能

  1. 01认证代理转发配置
  2. 02webctl 会话与导航命令
  3. 03网页快照与截图
  4. 04基于 ARIA 的查询和交互
  5. 05代理故障排查说明

适用场景

  1. 01在 Claude.ai 容器中自动操作浏览器
  2. 02通过快照检查网页
  3. 03与表单和页面控件交互
  4. 04排查 Chromium 代理隧道故障

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/oaustegard/claude-skills --skill using-webctl

安装后在 Claude Code 中输入/using-webctl确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

CHANGELOG.md
README.md
scripts/
auth_proxy.py
setup_webctl.py

详细介绍

在 Claude.ai 容器中使用 webctl

通过 webctl CLI 进行浏览器自动化,并在 Claude.ai 的出口流量受控环境中自动处理代理身份验证。

适用场景

  • 用户请求浏览器自动化、网页抓取或页面交互
  • webctl 命令因 ERR_TUNNEL_CONNECTION_FAILED 失败
  • Playwright/Chromium 需要通过经过身份验证的 HTTP 代理工作

核心问题

Claude.ai 容器通过经过身份验证的出口代理(带有 JWT 凭据的 HTTP_PROXY 环境变量)路由流量。Chromium 无法妥善处理 HTTPS CONNECT 隧道的代理身份验证,导致所有 HTTPS 导航失败,尽管 curl 可以正常工作。

解决方案

本地转发代理(端口 18080)会拦截 Chromium 连接,并在转发到实际出口代理前注入 Proxy-Authorization 标头。

设置步骤

1. 安装 webctl
pip install webctl --break-system-packages
webctl setup  # Downloads Chromium if needed
2. 部署身份验证代理模块

将 scripts/auth_proxy.py 复制到 webctl 的守护进程目录:

cp /mnt/skills/user/using-webctl/scripts/auth_proxy.py \
   /usr/local/lib/python3.12/dist-packages/webctl/daemon/
3. 修补会话管理器

对 /usr/local/lib/python3.12/dist-packages/webctl/daemon/session_manager.py 应用此补丁。

较新的 webctl 版本将上下文创建拆分为两个分支(移动设备模拟与桌面)。两个分支都必须接收代理配置。找到相应代码块(搜索 cfg = WebctlConfig.load(),后面跟着 if mode == "unattended" and cfg.mobile_emulation: 分支——大约在第 190 行):

cfg = WebctlConfig.load()
if mode == "unattended" and cfg.mobile_emulation:
    # Mobile emulation: cleaner pages, fewer ads, simpler layouts
    device = self._playwright.devices["Pixel 7"]
    context = await browser.new_context(
        storage_state=storage_state,
        **device,
    )
else:
    context = await browser.new_context(
        storage_state=storage_state, viewport={"width": 1280, "height": 720}
    )

替换为:

cfg = WebctlConfig.load()
from .auth_proxy import get_local_proxy_url
proxy_url = get_local_proxy_url()
proxy_config = {"server": proxy_url} if proxy_url else None
if mode == "unattended" and cfg.mobile_emulation:
    # Mobile emulation: cleaner pages, fewer ads, simpler layouts
    device = self._playwright.devices["Pixel 7"]
    context = await browser.new_context(
        storage_state=storage_state,
        proxy=proxy_config,
        **device,
    )
else:
    context = await browser.new_context(
        storage_state=storage_state, viewport={"width": 1280, "height": 720},
        proxy=proxy_config
    )

如果文件中只有一个 new_context 调用(较旧的 webctl 版本),就在该调用中注入 proxy=proxy_config,并将三行 proxy_url 放在它上方。

4. 验证
webctl start --mode unattended
webctl --quiet navigate "https://github.com"
webctl snapshot --interactive-only --limit 10
webctl stop

快速参考

会话管理
webctl start --mode unattended    # Headless browser
webctl stop                       # Full shutdown (use --keep-daemon to leave daemon running)
webctl status                     # Current state + console error counts
导航
webctl navigate "https://..."
webctl back / webctl forward / webctl reload
观察
webctl snapshot --interactive-only --limit 30   # Buttons, links, inputs
webctl snapshot --within "role=main"            # Scope to container
webctl query "role=button name~=Submit"         # Debug queries
webctl screenshot --path shot.png
交互
webctl click 'role=button name~="Submit"'
webctl type 'role=textbox name~="Email"' "[email protected]"
webctl type 'role=textbox name~="Search"' "query" --submit
webctl select 'role=combobox name~="Country"' --label "Germany"
查询语法
  • role=button — 按 ARIA 角色查询
  • name~="partial" — 包含匹配(推荐,更稳健)
  • name="exact" — 精确匹配
  • nth=0 — 有多个匹配项时选择第一个
等待条件
webctl wait network-idle
webctl wait 'exists:role=button name~="Continue"'
webctl wait 'url-contains:"/dashboard"'

故障排除

ERR_TUNNEL_CONNECTION_FAILED

身份验证代理未加载。请确认:

  1. auth_proxy.py 存在于 webctl 守护进程目录中
  2. 会话管理器已修补
  3. 重启守护进程:webctl stop && webctl start --mode unattended
多个匹配项错误

添加更具体的条件或使用 nth=0:

webctl click 'role=link name="Sign in" nth=0'
验证代理是否正在运行
netstat -tlnp | grep 18080

限制

  • 补丁仅对当前会话有效(容器重置后会清除)
  • 只能访问网络配置中允许的域名
  • 不支持 Firefox(出口策略禁止下载)

域名限制

在系统提示词的 <network_configuration> 中查看允许的域名。常见的允许域名包括:*.github.com、*.bsky.app 和允许的 API 端点。

输出过滤

减少上下文消耗:

webctl snapshot --interactive-only --limit 30    # Cap elements
webctl snapshot | grep -i "submit"               # Unix filtering
webctl --quiet navigate "..."                    # Suppress events

评论

支持 Markdown