MCPcopy Index your code
hub / github.com/bitsky-tech/bridgic-browser

github.com/bitsky-tech/bridgic-browser @v0.0.5

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.0.5 ↗ · + Follow
2,406 symbols 9,121 edges 83 files 1,540 documented · 64% updated 49d agov0.0.5 · 2026-05-18★ 75
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

English | 中文


Bridgic Browser 中文文档

Bridgic Browser 是一个基于 Playwright 构建、用于 LLM 驱动浏览器自动化的 Python 库。它提供 CLI 工具、Python 工具,以及面向 AI 智能体的 skills。

特性

  • 完善的 CLI 工具 — 67 个工具分为 15 类;可与各类 AI 智能体集成
  • 基于 Python 的工具 — 用于智能体 / 工作流代码生成;更易与 Bridgic 集成
  • 语义不变的快照 — 基于无障碍树与专门设计的 ref 生成算法,保证元素 ref 在页面重载后仍可对应同一元素
  • Skills — 用于引导探索与代码生成;兼容多数编程类智能体
  • 隐身模式(默认开启) — 模式感知反检测,覆盖 24+ 项 JS/CDP 指纹向量。已在公开 bot 检测基准套件上验证通过,详见下方 反检测 章节
  • 持久化与临时会话 — 默认持久化 profile($BRIDGIC_HOME/bridgic-browser/user_data/,默认 ~/.bridgic/...);传入 clear_user_data=True 可开启临时会话(无 profile)
  • 嵌套 iframe 支持 — 支持在多层嵌套 iframe 内对 DOM 元素进行操作

快速开始

与 AI 集成

使用 Bridgic Browser 最简单的方式,是配合编程智能体或 AI 助手(例如 Claude Code、Cursor、Codex、OpenClaw)。你可以通过两种方式使用:Skill 或 Plugin。在这两种方式下,Bridgic Browser 都会被自动安装。

方式 1:让 AI 直接控制浏览器,实时完成任务。

要使用这种方式,请安装 Bridgic Browser 提供的 Skill:

npx skills add bitsky-tech/bridgic-browser --skill bridgic-browser

安装后,Skill 会出现在你的 agent 目录中(例如 Claude Code 常见为 .claude/skills/bridgic-browser/,Cursor 常见为 .agents/skills/bridgic-browser/)。

方式 2:让 AI 以更少 token 生成可复用的浏览器自动化脚本。

要使用这种方式,请安装 AmphiLoop 提供的 Plugin。AmphiLoop 是一套全新的方法论、技术栈和工具链,可通过自然语言构建 AI 智能体。

手动安装

pip install bridgic-browser

安装后,安装 Playwright 浏览器:

playwright install chromium

CLI 工具用法

bridgic-browser open --headed https://example.com
bridgic-browser snapshot
# 'f0201d1c' 是「Learn more」链接的 ref
bridgic-browser click f0201d1c
bridgic-browser screenshot page.png
bridgic-browser close

Python 工具集成

首先构建工具:

from bridgic.browser.session import Browser
from bridgic.browser.tools import BrowserToolSetBuilder, ToolCategory

# 创建浏览器实例
browser = Browser(headless=False)

async def create_tools(browser):
    # 为智能体构建聚焦工具集
    builder = BrowserToolSetBuilder.for_categories(
        browser,
        ToolCategory.NAVIGATION,
        ToolCategory.SNAPSHOT,
        ToolCategory.ELEMENT_INTERACTION,
        ToolCategory.CAPTURE,
        ToolCategory.WAIT,
    )
    tools = builder.build()["tool_specs"]
    return tools

其次(可选),构建使用上述工具集的 Bridgic 智能体:

import os
from bridgic.llms.openai import OpenAILlm, OpenAIConfiguration
async def create_llm():
    _api_key = os.environ.get("OPENAI_API_KEY")
    _model_name = os.environ.get("OPENAI_MODEL_NAME")

    llm = OpenAILlm(
        api_key=_api_key,
        configuration=OpenAIConfiguration(model=_model_name),
        timeout=60,
    )
    return llm

from bridgic.core.agentic.recent import ReCentAutoma, StopCondition
from bridgic.core.automa import RunningOptions
async def create_agent(llm, tools):
    browser_agent = ReCentAutoma(
        llm=llm,
        tools=tools,
        stop_condition=StopCondition(max_iteration=10, max_consecutive_no_tool_selected=1),
        running_options=RunningOptions(debug=True),
    )
    return browser_agent

async def main():
    tools = await create_tools(browser)
    llm = await create_llm()
    agent = await create_agent(llm, tools)
    result = await agent.arun(
        goal=(
            "Summarize the 'Learn more' page of example.com for me"
        ),
        guidance=(
            "Do the following steps one by one:\n"
            "1. Navigate to https://example.com\n"
            "2. Click the 'Learn more' link\n"
            "3. Take a screenshot of the 'Learn more' page\n"
            "4. Summarize the page content in one sentence and tell me how to access the screenshot.\n"
        ),
    )
    print("\n\n*** Final Result: ***\n\n")
    print(result)

    await browser.close()

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

浏览器 API 用法

也可以直接调用底层 Browser API 控制浏览器。

from bridgic.browser.session import Browser

browser = Browser(headless=False)

async def main():
    await browser.navigate_to("https://example.com")
    snapshot = await browser.get_snapshot()
    print(snapshot.tree)  # 树格式:- role "name" [ref=f0201d1c]
    for ref, data in snapshot.refs.items():
        if data.name == "Learn more":
            learn_more_ref = ref
            break
    print(f"Found ref for 'Learn more': {learn_more_ref}")
    await browser.click_element_by_ref(learn_more_ref)
    await browser.take_screenshot(filename="page.png")
    await browser.close()

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

CLI 工具

bridgic-browser 提供命令行界面,用于在终端控制浏览器(67 个工具、15 类)。持久化 daemon 进程持有浏览器实例;每次 CLI 调用通过 Unix 域套接字连接后立即退出。

配置

浏览器选项自动从以下来源加载(CLI daemon 和 SDK Browser() 共用),优先级从低到高(后者覆盖前者):

来源 示例
默认值 headless=Trueclear_user_data=False(持久化 profile)
$BRIDGIC_HOME/bridgic-browser/bridgic-browser.json 用户级持久配置(默认 ~/.bridgic/...
./bridgic-browser.json 项目本地配置(daemon 启动时的工作目录)
环境变量 skills/bridgic-browser/references/env-vars.md

有界面浏览器说明:headless=false 且启用隐身模式时,bridgic 会自动切换到系统 Chrome(如已安装),以获得更好的反检测效果(Chrome for Testing 会被 Google OAuth 拦截)。 若需覆盖此行为,请设置: - channel:例如 ”chrome””msedge” - executable_path:浏览器可执行文件的绝对路径

反检测

bridgic 内置工业级隐身层,在不依赖定制 Chromium 二进制、代理、CAPTCHA 解算器 的前提下,绕过绝大多数基于 JavaScript 指纹的 bot 检测。设计模式感知:有头 模式利用真实系统 Chrome 的 TLS 真实性,无头模式应用更完整的 JS + CDP 补丁集合。 架构详情见 docs/INTERNALS.md#mode-aware-stealth-design

Benchmark

最近一次验证:2026-05-12(Playwright Chromium 143 / 系统 Chrome 147,macOS)。

站点 bridgic 结果
bot.sannysoft.com 0 / 57 fail(两种模式)
bot.incolumitas.com 0 fail(两种模式)
browserscan.net/bot-detection 0 abnormal / 19 normal(两种模式)
demo.fingerprint.com/web-scraping 通过(有头模式)
recaptcha-demo.appspot.com (reCAPTCHA v3) 评分 = 0.9(两种模式)

覆盖范围

24+ 项检测向量,在 JS + CDP 层完成补丁:

  • 反内省基础设施Function.prototype.toString 拦截,挫败 .toString() 探测
  • navigatorwebdriver(从 Navigator.prototype 上整体 delete,与 --disable-blink-features=AutomationControlled 语义一致;'webdriver' in navigator 返回 false)、pluginsmimeTypes(继承原生 PluginArray / MimeTypeArray prototype;item(i) 按 Web IDL §3.2.4 做 uint32 截断)、languagesdeviceMemoryhardwareConcurrencyconnectionpermissions.query
  • window / documentchrome(完整 runtime/csi/loadTimes)、 outerWidth/HeighthasFocus/hidden/visibilityStateNotification.permission
  • WebGL — UNMASKED_VENDOR / UNMASKED_RENDERER(替换 SwiftShader / 通用厂商泄漏)
  • UA / Sec-CH-UA(无头模式独占,通过 CDP Emulation.setUserAgentOverride) — navigator.userAgentuserAgentData.brands
  • Web Worker / SharedWorker / Service Worker(通过构造器 wrap + importScripts 实现 race-proof 注入)— 主线程↔worker 一致性,涵盖 deviceMemorylanguagesvendorproductSubvendorSub、WebGL
  • CDP attach 检测Debugger.setSkipAllPausesconsole.*Error 实参的 pre-stringify 包裹(阻断 error.stack getter 探测)
  • devtools-detector 库对抗console.table 计时归一化、devtoolsFormatters 锁定、Function 构造器 debugger 关键字剥除

逐向量实现细节见 docs/INTERNALS.md#stealth-js-init-script--patched-properties

JSON 来源支持任意 Browser 构造参数:

{
  "headless": false,
  "proxy": {"server": "http://proxy:8080", "username": "u", "password": "p"},
  "viewport": {"width": 1280, "height": 720},
  "locale": "zh-CN",
  "timezone_id": "Asia/Shanghai"
}
# 单次环境变量覆盖
BRIDGIC_BROWSER_JSON='{"headless":false,"locale":"zh-CN"}' bridgic-browser open URL
# 单次临时会话(无持久化 profile)
BRIDGIC_BROWSER_JSON='{"clear_user_data":true}' bridgic-browser open URL

多实例隔离(BRIDGIC_HOME

默认所有状态存储在 ~/.bridgic 下。设置 BRIDGIC_HOME 可同时运行多个独立的 daemon 实例——各自拥有独立的 socket、日志、用户数据和配置:

# 实例 1(默认)
bridgic-browser open https://site-a.com

# 实例 2(独立 home 目录)
BRIDGIC_HOME=/tmp/b2 bridgic-browser open https://site-b.com

# 各实例独立操作
bridgic-browser snapshot                        # site-a 快照
BRIDGIC_HOME=/tmp/b2 bridgic-browser snapshot   # site-b 快照

# 分别关闭各实例
bridgic-browser close
BRIDGIC_HOME=/tmp/b2 bridgic-browser close

SDK 同进程多实例隔离使用 Browser(user_data_dir=...) 为每个实例指定不同的 profile 路径。完全的进程级隔离则在启动子进程前设置 BRIDGIC_HOME 环境变量。详见 skills/bridgic-browser/references/env-vars.md

存储状态(跨实例共享登录态)

将一个浏览器实例的 cookies 和 localStorage 导出,导入到另一个实例中——适用于跨实例共享登录会话,或将认证状态持久化以便后续运行复用:

# 1. 在实例 A 中登录目标网站
bridgic-browser open https://github.com --headed
# ... 在浏览器中完成登录 ...

# 2. 导出存储状态(cookies + localStorage)
bridgic-browser storage-save /tmp/github-login.json

# 3. 在另一个实例中导入(可以使用不同的 BRIDGIC_HOME)
BRIDGIC_HOME=/tmp/b2 bridgic-browser open https://github.com --headed
BRIDGIC_HOME=/tmp/b2 bridgic-browser storage-load /tmp/github-login.json
BRIDGIC_HOME=/tmp/b2 bridgic-browser reload   # 刷新页面以应用导入的 cookies

# 实例 B 现在已使用与实例 A 相同的会话完成登录

导出的 JSON 文件包含浏览器访问过的所有域的全部 cookies(包括 HttpOnly / Secure 属性的)和 localStorage 条目。

存储状态文件跨模式兼容——可以从 headed 会话导出后导入到 headless 会话中使用(反之亦然),登录态会完整保留。这在需要认证的自动化场景中特别实用:先在 headed 模式下手动登录(处理验证码、2FA 等交互),导出存储状态,之后在 headless 自动化运行中直接复用。

SDK 用法:

import asyncio
from bridgic.browser import Browser

async def main():
    # 1. 导出:在有头模式下交互登录,然后保存存储状态
    async with Browser(headless=False) as browser:
        await browser.navigate_to("https://github.com")
        # ... 在浏览器中完成登录 ...
        await browser.save_storage_state("/tmp/github-login.json")

    # 2. 导入:在新的(无头)实例中复用登录会话
    async with Browser(headless=True, user_data_dir="/tmp/sdk-profile") as browser:
        await browser.restore_storage_state("/tmp/github-login.json")
        await browser.navigate_to("https://github.com")
        snap = await browser.get_snapshot(interactive=True)
        print(snap.tree)  # Dashboard — 已登录

asyncio.run(main())

CDP 模式(连接已有浏览器)

bridgic-browser 可以通过 Chrome DevTools Protocol 连接到已经运行的 Chrome/Chromium 实例,而非启动新浏览器。

开启远程调试端点有两种方式。

方式一 —— Chrome 144+ 浏览器内 UI 启用(无需重启 Chrome)。 在你日常使用的 Chrome 中打开 chrome://inspect/#remote-debugging,按对话框提示允许远程调试连接即可。Chrome 会在本地开启调试端点,并把连接信息写入 user data 目录根部的 DevToolsActivePort 文件:

平台 路径
macOS ~/Library/Application Support/Google/Chrome/DevToolsActivePort
Linux ~/.config/google-chrome/DevToolsActivePort
Windows %LOCALAPPDATA%\Google\Chrome\User Data\DevToolsActivePort

文件总共两行 —— 端口号 + 浏览器级 WebSocket 路径:

9222
/devtools/browser/f8632266-41b6-4eb8-8239-d48a86bb44b1

由于 bridgic 的 --cdp auto 本身就会扫描这些标准 profile 目录里的 DevToolsActivePort,你无需任何额外参数即可直接连接:

bridgic-browser open https://example.com --cdp auto

会话激活期间 Chrome 会在顶部显示 "Chrome 正在受到自动测试软件的控制" 横幅,并可能在每次新建调试会话时再次弹出确认对话框。来源:Chrome DevTools MCP 博客chrome-devtools-mcp README。完整说明见 docs/CDP_MODE.md

方式二 —— 启动参数(Chrome <144 或需要独立 profile 时)。 使用 --remote-debugging-port 启动 Chrome:

# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
    --remote-debugging-port=9222 --user-data-dir=/tmp/cdp-profile

# Linux
google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/cdp-profile

然后使用 --cdp 连接:

bridgic-browser open https://example.com --cdp 9222
bridgic-browser open https://example.com --cdp ws://localhost:9222/devtools/browser/...
bridgic-browser open https://example.com --cdp wss://cloud.example.com/chromium?token=...
bridgic-browser open https://example.com --cdp auto
格式 说明
9222 端口号 -- 向 localhost:9222/json/version 查询 WebSocket URL
ws://... / wss://... 直接 WebSocket URL(原始 CDP 或 Playwright WS 协议),原样传递
http://host:port HTTP 发现端点 -- 向该主机的 /json/version 查询
auto 自动扫描本地 Chrome/Chromium/Brave 配置目录(含 Canary 变体),查找活跃的 DevToolsActivePort 文件

Tab 可见性: 连接到用户已在运行的 Chrome 后,bridgic 只看得到自己打开的页面 —— 连接时自动创建的初始空白页、new-tab 新建的标签,以及由这些页面派生出来的弹窗(在 <a target="_blank">普通左键点击、或 JavaScript window.open(),通过 Page.opener() 自动归属)。用户用 Cmd+click(macOS)/ Ctrl+click(Win/Linux)/ 中键点击 / Cmd+T / 地址栏新开的标签不会被采纳 —— Cmd/Ctrl/中键点击会走 Chromium 的"背景 tab 导航"路径,opener 在 browser 进程层被剥离;Cmd+T 和地址栏开 tab 则根本就没有 opener 关系。两种情况 bridgic 都看不到。用户其它已存在的标签对 bridgic 的 tabs / switch-tab / close-tab 也是不可见的。 这是一条隐私边界,避免 LLM 驱动的 bridgic 误切到或关闭用户的私人工作 tab。如需操作已打开的页面,请通过 bridgic 重新导航到该 URL。默认情况下,bridgic 当前 tab 派生的弹窗会自动接管为新的活动 tab(auto_follow_popups=True);如需保持活动指针不动,可用 Browser(auto_follow_popups=False)。完整采纳对照表见 docs/CDP_MODE.md#tab-ownership-in-cdp-mode

关闭行为: bridgic-browser close 会断开与远程浏览器的连接,但不会终止 Chrome 进程。浏览器继续运行,可以重新连接。

使用场景: - 复用已有 Chrome 会话及其登录状态和扩展 - 连接云端浏览器服务(Browserless、Steel.dev 等) - 自动化开放 CDP 端口的 Electron 应用

SDK 等效用法:

browser = Browser(cdp="ws://localhost:9222/devtools/browser/...")

命令列表

类别 命令
导航 open, back, forward, reload, search, info
快照 snapshot [-i] [-f\|-F] [-l N] [-s FILE]
元素交互 click, double-click, hover, focus, fill, select, options, check, uncheck, scroll-to, drag, upload, fill-form
键盘 press, type, key-down, key-up
鼠标 scroll, mouse-move, mouse-click, mouse-drag, mouse-down, mouse-up
等待 wait [SECONDS] [TEXT] [--gone]
标签页 tabs, new-tab, switch-tab, close-tab
执行 eval, eval-on
捕获 screenshot, pdf
网络 network-start, network-stop, network, wait-network
对话框 dialog-setup, dialog, dialog-remove
存储 storage-save, storage-load, cookies-clear, cookies, cookie-set
校验

Core symbols most depended-on inside this repo

wait_for
called by 91
bridgic/browser/session/_browser.py
get_current_page
called by 79
bridgic/browser/session/_browser.py
_raise_state_error
called by 78
bridgic/browser/session/_errors.py
_raise_operation_error
called by 76
bridgic/browser/session/_errors.py
send_command
called by 75
bridgic/browser/cli/_client.py
_start
called by 72
bridgic/browser/session/_browser.py
_ok
called by 69
bridgic/browser/cli/_commands.py
_err
called by 67
bridgic/browser/cli/_commands.py

Shape

Method 1,660
Function 525
Class 218
Route 3

Languages

Python100%

Modules by API surface

tests/unit/test_cli.py382 symbols
tests/unit/test_browser.py285 symbols
tests/unit/test_snapshot_parse.py206 symbols
bridgic/browser/session/_browser.py155 symbols
tests/unit/test_tools.py133 symbols
bridgic/browser/cli/_daemon.py86 symbols
tests/unit/test_stealth.py77 symbols
bridgic/browser/cli/_commands.py76 symbols
tests/integration/test_tools.py75 symbols
tests/unit/test_download.py55 symbols
tests/unit/test_browser_methods.py55 symbols
tests/unit/test_video_recorder.py52 symbols

For agents

$ claude mcp add bridgic-browser \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact