Skip to main content

Agent Webview

面向 AI Agent 的隔离式本地 WebView 调试服务

通过稳定的 HTTP API 管理隐藏浏览器、检查 DOM、执行 JavaScript,并观察页面事件。

简体中文 · English

PyPI Python CI License

[!NOTE] 项目仍处于 0.x 预览阶段。CLI、运行信息文件和 /v1 HTTP API 是当前的 公共兼容边界;包内 Python 模块暂不承诺稳定。

✨ 核心特性

能力 说明
进程级隔离 每个会话使用独立 pywebview worker 和无痕窗口
Agent 友好 OpenAPI、结构化 JSON、Bearer Token 和稳定的 /v1 接口
默认隐藏 窗口按需显示,适合后台调试和多会话并行
页面操作 支持导航、DOM 查询、输入、点击和 JavaScript 执行
可观测性 支持 DOM 事件、DOM 变更和页面网络活动的长轮询采集
代理调试 支持全局或单窗口 HTTP/HTTPS 代理,并异步查询出口 IP 与归属地
Cookie 快照 可保存 Cookie,并在新会话中尽力恢复
跨平台 支持 Windows、macOS 和带 GTK/Qt 后端的 Linux

🧱 工作方式

Agent / Python 脚本
        │
        │ HTTP + Bearer Token
        ▼
agent-webview 控制器
        ├── 独立 worker ── 无痕窗口 A
        ├── 独立 worker ── 无痕窗口 B
        └── 独立 worker ── 无痕窗口 C

控制器本身不创建可见窗口。POST /v1/sessions 每次启动一个新的 worker 进程;会话内的后续请求复用同一窗口,直到会话被删除。

📦 安装

需要 Python 3.10 或更高版本。

python -m pip install agent-webview

requirements.txt 中建议限制在同一次版本系列:

agent-webview~=0.1.0

发行包名、Python 模块名和命令名分别是:

  • pip install agent-webview
  • import agent_webview
  • agent-webview

平台依赖

平台 WebView 后端
Windows WebView2;现代 Windows 通常已预装 WebView2 Runtime
macOS 系统 WebKit
Linux 安装 agent-webview[linux-gtk]agent-webview[linux-qt]

🚀 快速开始

1. 启动控制器

agent-webview

默认监听 http://127.0.0.1:8765。启动后会生成一份运行信息 JSON,包含服务 地址、进程号、OpenAPI 地址和随机 Bearer Token。查询该文件的位置:

agent-webview --print-runtime-file

默认数据位于操作系统的当前用户数据目录,不会写入当前项目目录。需要自定义位置时:

agent-webview \
  --data-dir ./webview-data \
  --runtime-file ./agent-webview-runtime.json

需要让该控制器创建的所有窗口都使用同一代理时,在启动时声明:

agent-webview --proxy http://127.0.0.1:7890

2. 创建并控制会话

下面的 Python 示例读取运行信息、创建隐藏会话、等待窗口就绪,然后读取页面标题:

import json
import subprocess
import time
from pathlib import Path

import httpx

runtime_path = Path(
    subprocess.check_output(
        ["agent-webview", "--print-runtime-file"],
        text=True,
    ).strip()
)
runtime = json.loads(runtime_path.read_text(encoding="utf-8"))
headers = {"Authorization": f"Bearer {runtime['token']}"}

with httpx.Client(
    base_url=runtime["base_url"],
    headers=headers,
    timeout=30,
) as client:
    session = client.post(
        "/v1/sessions",
        json={"url": "https://example.com", "visible": False},
    ).raise_for_status().json()
    session_id = session["session_id"]

    for _ in range(100):
        state = client.get(f"/v1/sessions/{session_id}").raise_for_status().json()
        if (state.get("window") or {}).get("ready"):
            break
        time.sleep(0.1)
    else:
        raise TimeoutError("浏览器窗口未就绪")

    result = client.post(
        f"/v1/sessions/{session_id}/javascript/evaluate",
        json={"code": "document.title", "timeout": 10},
    ).raise_for_status().json()
    print(result["value"])

    client.delete(f"/v1/sessions/{session_id}").raise_for_status()

服务启动后也可以直接打开运行信息中的 docs_url,或访问 /docs/openapi.json 查看完整接口定义。

🔌 主要接口

方法 路径 用途
POST /v1/sessions 创建独立无痕会话
GET /v1/sessions 列出会话和进程信息
GET /v1/sessions/{id} 获取窗口、句柄和进程状态
GET /v1/sessions/{id}/proxy 查询代理配置、出口 IP 和归属地
DELETE /v1/sessions/{id} 销毁会话
POST /v1/sessions/{id}/navigate 导航到新地址
POST /v1/sessions/{id}/javascript/evaluate 执行表达式并返回结果
POST /v1/sessions/{id}/javascript/execute 执行 JavaScript 语句
POST /v1/sessions/{id}/dom/query 查询 DOM 元素
POST /v1/sessions/{id}/dom/input 设置输入值并触发事件
POST /v1/sessions/{id}/dom/click 调用元素的 DOM click()
POST /v1/sessions/{id}/dom/listeners 添加 DOM 事件监听
PUT /v1/sessions/{id}/instrumentation 配置网络和 DOM 探针
GET /v1/sessions/{id}/events 长轮询获取事件
GET /v1/sessions/{id}/cookies 获取 Cookie
POST /v1/sessions/{id}/cookie-snapshots 保存 Cookie 快照
GET /v1/cookie-snapshots 列出 Cookie 快照
POST /v1/sessions/{id}/window/show 显示窗口
POST /v1/sessions/{id}/window/hide 隐藏窗口

创建会话后,响应会提供:

  • session_id:控制器会话标识。
  • window_id:服务生成的稳定窗口标识。
  • native_window_id:GUI 后端提供的原生窗口句柄,窗口未创建时可能为 null
  • pid:实际 pywebview worker 进程号。
  • launcher_pid:部分 Windows 虚拟环境中的启动器进程号,否则为 null

🌐 代理调试

控制器启动时传入 --proxy 会设置全局代理,之后创建的所有窗口都会使用它,直到 控制器进程退出。没有全局代理时,可以只为某个窗口在创建请求中传入 proxy

session = client.post(
    "/v1/sessions",
    json={
        "url": "https://example.com",
        "visible": False,
        "proxy": "http://127.0.0.1:7890",
    },
).raise_for_status().json()

全局代理优先于创建请求中的窗口代理,保证该控制器下的所有窗口使用同一代理。 代理地址支持 http://https://,暂不支持 SOCKS、用户名密码认证、路径或查询 参数。Windows 需要 WebView2;macOS 的原生代理能力需要 macOS 14 或更高版本。

窗口会立即加载目标页面。出口 IP 与归属地由后台线程通过固定的第三方服务查询, 不会等待查询结束才放行 WebView。查询成功后,可见窗口标题会变为类似:

[已进入代理模式 · 203.0.113.8 · 中国 / 上海市 / 上海] Agent Webview

隐藏窗口或程序化调用应使用独立状态接口:

proxy = client.get(
    f"/v1/sessions/{session_id}/proxy",
    params={"timeout": 10},
).raise_for_status().json()

if proxy["state"] == "active":
    print(proxy["server"], proxy["ip"], proxy["location"])

timeout 默认为 0,此时立即返回;可设置为最多 30 秒,仅让这一次状态请求等待 后台查询,不影响 WebView。响应中的状态含义如下:

  • disabled:该窗口没有声明代理。
  • checking:窗口已按代理配置启动,出口信息仍在后台查询。
  • active:固定查询服务已通过该代理成功返回出口 IP 和归属地。
  • unavailable:本次查询没有结果;页面继续正常工作,该状态本身不能断定代理失败。

查询完成时也会产生 proxy 事件,可通过现有事件长轮询接口监听。查询服务地址固定 在实现内部,不接受 CLI 或 HTTP API 覆盖。

🔎 页面观测

通过 PUT /v1/sessions/{id}/instrumentation 可以开启:

  • network:采集页面内的 fetchXMLHttpRequest、WebSocket 和 Performance Resource 记录。
  • mutations:采集 DOM 变更,可用 mutation_selector 缩小范围。
  • capture_request_bodies / capture_response_bodies:按需采集请求或响应体。

随后使用 GET /v1/sessions/{id}/events?after=0&timeout=20 长轮询事件,下一次 请求将返回的 latest_sequence 作为 afterkinds 参数可过滤 domnetworkmutationlifecycleproxy

网络探针不是浏览器底层代理,不能保证捕获 Service Worker、缓存命中、扩展流量 或所有响应体。需要协议级调试时,可以在创建会话时设置 remote_debugging_port,并使用后端支持的 DevTools 协议。

🍪 Cookie 快照

Cookie 快照默认保存在当前用户数据目录,也可以通过 --data-dir 指定位置。创建 新会话时传入 snapshot_id 即可尝试恢复;请求中显式提供的 cookies 会覆盖快照 内同名、同域、同路径的 Cookie。

恢复存在浏览器后端限制:

  • pywebview 可以读取包含 HttpOnly 在内的 Cookie。
  • 通用跨后端恢复依赖 document.cookie,因此无法恢复 HttpOnly Cookie。
  • Domain、SameSite、Secure、过期时间和浏览器策略可能拒绝部分 Cookie。
  • 快照不包含 IndexedDB、Local Storage、Service Worker 或缓存。

Cookie 快照和运行信息文件都应按敏感数据处理,不应提交到版本控制系统。

⚙️ 常用配置

参数 默认值 说明
--host 127.0.0.1 控制器监听地址
--port 8765 控制器监听端口
--token 随机生成 固定 Bearer Token
--data-dir 当前用户数据目录 Cookie 快照目录
--runtime-dir 当前用户运行目录 worker 运行文件目录
--runtime-file 当前用户运行目录 控制器运行信息文件
--proxy 关闭 所有新窗口使用的 HTTP/HTTPS 代理
--allow-remote 关闭 允许监听非本机地址
--log-level info 日志级别
--json-logs 关闭 输出 JSON 日志

固定 Token 时优先使用 AGENT_WEBVIEW_TOKEN 环境变量,避免令牌出现在命令历史 和进程参数中。全局代理也可以通过 AGENT_WEBVIEW_PROXY 设置。

🔐 安全说明

本服务允许调用方执行任意页面 JavaScript,并可能读取浏览器 Cookie。请遵守以下 边界:

  • 只在可信设备和可信网络中运行。
  • 不要共享运行信息文件、Token 或 Cookie 快照。
  • 代理窗口会把出口 IP 发送给内置的第三方归属地查询服务。
  • 默认只监听本机;非本机地址必须显式传入 --allow-remote
  • 任务结束后删除会话,释放 worker 进程和 WebView 资源。
  • 安全问题请按照安全策略私下报告。

📐 设计边界

  • 无痕隔离依靠“一会话一进程”和 private_mode=True
  • 所有 worker 接口只监听随机本机端口,并使用独立内部令牌。
  • 控制器重启不会恢复仍在运行的 worker 会话。
  • DOM click() 不等同于操作系统级鼠标事件。
  • 当前不提供截图接口,因为 pywebview 没有统一的跨后端页面截图 API。
  • 该项目可以把 WebView 流量转交给已有代理,但本身不是代理服务器,也不是完整的 浏览器自动化框架。

公共兼容范围和版本规则见 API 稳定性说明

🛠️ 参与开发

git clone https://github.com/Yuv96/agent-webview.git
cd agent-webview
uv sync --extra dev
uv run ruff check src tests scripts
uv run mypy
uv run pytest
uv run python scripts/smoke_service.py

提交代码前请阅读 贡献指南

📄 License

本项目基于 MIT License 发布。

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agent_webview-0.1.2.tar.gz (165.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agent_webview-0.1.2-py3-none-any.whl (41.0 kB view details)

Uploaded Python 3

File details

Details for the file agent_webview-0.1.2.tar.gz.

File metadata

  • Download URL: agent_webview-0.1.2.tar.gz
  • Upload date:
  • Size: 165.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for agent_webview-0.1.2.tar.gz
Algorithm Hash digest
SHA256 cd38aaf2a60c22902a727227fa22c807f3043d5ff6d12509d745740b7f7a47fa
MD5 7090b1495d9b56fa21fe63ca352336fd
BLAKE2b-256 2a1716fdc61258b27415d174f011393f4f456a841a184d8cab4e1cf857407ccf

See more details on using hashes here.

Provenance

The following attestation bundles were made for agent_webview-0.1.2.tar.gz:

Publisher: publish.yml on Yuv96/agent-webview

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file agent_webview-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: agent_webview-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 41.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for agent_webview-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 45c3d89f33a9fccc960ac36cbfd7522ff41540e4c0a756d841917e7c5abc66b0
MD5 b18344179cdd036884900a336b227435
BLAKE2b-256 0b35057fcdf3322652a369df042ae2c1260773b5992bc6fced25d966542b12f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for agent_webview-0.1.2-py3-none-any.whl:

Publisher: publish.yml on Yuv96/agent-webview

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page