Local API 文档

通过本地 HTTP 接口自动化管理环境与浏览器。

架构说明

EasyBrowser 采用单浏览器实例 + 多 Tab 环境隔离架构:

基础信息

项目说明
地址http://127.0.0.1:50325
GET 参数Query String
POST 参数JSON Body

响应格式

// 成功
{ "code": 0, "data": {...}, "msg": "success" }

// 失败
{ "code": -1, "data": {}, "msg": "错误描述" }

认证(可选)

默认无需认证。开启「API 安全校验」后需携带:

Authorization: Bearer <your_api_key>

账户信息

GET/api/v1/account/info

返回

{
  "code": 0,
  "data": {
    "email": "user@gmail.com",
    "expire_at": "2026-06-19 00:00:00",
    "activated_at": "2026-05-01 12:00:00",
    "max_containers": 50,
    "used_containers": 12,
    "left_containers": 38
  },
  "msg": "success"
}
字段说明
email账户邮箱
expire_at到期时间
activated_at账户创建时间
max_containers环境总数上限,VIP/企业定制为 null 表示不限
used_containers已创建环境数
left_containers剩余可创建数,VIP/企业定制为 null 表示不限

查询环境列表

GET/api/v1/container/list

支持 name、tag 模糊搜索。

参数

参数必需说明
id精确查询单个
name名称模糊搜索
tag标签模糊搜索
page页码(默认1)
page_size每页数量(默认50,最大100)

返回

{
  "code": 0,
  "data": {
    "list": [{
      "id": "uuid-xxx",
      "name": "Facebook账号1",
      "proxy": "socks5://user:pass@1.2.3.4:1080",
      "tag": "Facebook",
      "defaultUrl": "https://facebook.com",
      "account": "myemail@gmail.com",
      "twofa_secret": "JBSWY3DPEHPK3PXP",
      "notes": "主力号",
      "created_at": 1716091200,
      "last_opened": 1716177600
    }],
    "page": 1,
    "page_size": 50
  },
  "msg": "success"
}
字段类型说明
idstring环境唯一ID(UUID)
namestring环境名称
proxystring|null代理地址 protocol://user:pass@host:port
tagstring|null标签/分组
defaultUrlstring|null启动时默认打开的URL
accountstring|null平台账号
twofa_secretstring|nullTOTP 2FA 密钥(Base32)
notesstring|null备注
created_atnumber创建时间(Unix时间戳,秒)
last_openednumber|null最后打开时间(Unix时间戳,秒)

查询运行中的环境

GET/api/v1/container/list_running

返回

{
  "code": 0,
  "data": {
    "list": [
      { "id": "uuid-xxx", "name": "Facebook账号1", "cdp_id": "xxx", "tag": "Facebook" }
    ]
  },
  "msg": "success"
}
字段说明
id环境ID
name环境名称
cdp_id浏览器内部容器ID
tag标签

新建环境

POST/api/v1/container/create

参数(JSON Body)

参数必需说明
name环境名称
proxyprotocol://user:pass@host:port
tag标签
defaultUrl默认打开URL
account账号
password密码
twofa_secret2FA密钥(Base32)
notes备注
cookieCookie JSON数组字符串

返回

{ "code": 0, "data": { "id": "uuid-xxx", "name": "...", "created_at": 1716091200 }, "msg": "success" }

更新环境

POST/api/v1/container/update

只传需要更新的字段。传空字符串可清空。

参数(JSON Body)

参数必需说明
id环境ID
name / proxy / tag / defaultUrl / account / password / twofa_secret / notes要更新的字段

返回

{ "code": 0, "data": {}, "msg": "success" }

删除环境

POST/api/v1/container/delete

会同时清理浏览器容器数据和本地存储。运行中的Tab会先关闭。

参数(JSON Body)

{ "ids": ["uuid-1", "uuid-2"] }

返回

{ "code": 0, "data": {}, "msg": "success" }

获取2FA验证码

GET/api/v1/container/totp?id=xxx

返回

{ "code": 0, "data": { "code": "482916", "remaining": 18 }, "msg": "success" }
字段说明
code6位TOTP验证码
remaining剩余有效秒数(30秒周期)

启动浏览器

GET/api/v1/browser/start

幂等操作,已运行时直接返回成功。

返回

{ "code": 0, "data": { "debug_port": "9876" }, "msg": "success" }
字段说明
debug_port浏览器远程调试端口,用于 Playwright/CDP 连接

关闭浏览器

GET/api/v1/browser/stop

关闭浏览器进程,所有Tab都会关闭。

返回

{ "code": 0, "data": {}, "msg": "success" }

打开新Tab-并指定环境

GET/api/v1/browser/new_tab

自动应用环境的代理、指纹、Cookie。浏览器未启动时会自动启动。

参数

参数必需说明
id环境ID
url打开的URL(默认用环境的 defaultUrl)

返回

{ "code": 0, "data": { "target_id": "xxxxxxxx" }, "msg": "success" }
字段说明
target_idTab唯一标识,可用于 close_tab 和 CDP 连接

关闭Tab

GET/api/v1/browser/close_tab

参数

参数必需说明
id环境ID
target_idTab ID(不传则关闭最近的)

返回

{ "code": 0, "data": {}, "msg": "success" }

获取所有Tab信息

GET/api/v1/browser/tab_list

返回

{
  "code": 0,
  "data": {
    "list": [{
      "target_id": "xxxxxxxx",
      "url": "https://facebook.com/home",
      "container_id": "uuid-xxx",
      "container_name": "Facebook账号1"
    }]
  },
  "msg": "success"
}
字段说明
target_idTab唯一标识
urlTab当前访问的URL
container_id所属环境ID
container_name所属环境名称

Python 脚本示例

import requests

BASE = "http://127.0.0.1:50325"
# headers = {"Authorization": "Bearer your_key"}  # 开启安全校验时

# 创建环境
resp = requests.post(f"{BASE}/api/v1/container/create", json={
    "name": "测试环境",
    "proxy": "socks5://user:pass@1.2.3.4:1080",
    "tag": "测试",
    "defaultUrl": "https://google.com",
    "twofa_secret": "JBSWY3DPEHPK3PXP"
})
env_id = resp.json()["data"]["id"]

# 启动 + 打开Tab
requests.get(f"{BASE}/api/v1/browser/start")
resp = requests.get(f"{BASE}/api/v1/browser/new_tab", params={"id": env_id})
tab_id = resp.json()["data"]["target_id"]

# 获取2FA
totp = requests.get(f"{BASE}/api/v1/container/totp", params={"id": env_id}).json()
print(f"验证码: {totp['data']['code']}")

# 关闭
requests.get(f"{BASE}/api/v1/browser/close_tab", params={"id": env_id, "target_id": tab_id})
requests.get(f"{BASE}/api/v1/browser/stop")
requests.post(f"{BASE}/api/v1/container/delete", json={"ids": [env_id]})

Python SDK

依赖:pip install requests

SDK 源码

import requests

class EasyBrowserAPI:
    def __init__(self, base_url="http://127.0.0.1:50325", api_key=None, timeout=30):
        self.base = base_url.rstrip("/")
        self.timeout = timeout
        self.headers = {"Authorization": f"Bearer {api_key}"} if api_key else {}

    def _get(self, path, params=None):
        r = requests.get(f"{self.base}{path}", params=params, headers=self.headers, timeout=self.timeout)
        return self._check(r.json())

    def _post(self, path, data=None):
        r = requests.post(f"{self.base}{path}", json=data, headers=self.headers, timeout=self.timeout)
        return self._check(r.json())

    def _check(self, res):
        if res["code"] != 0: raise Exception(res["msg"])
        return res["data"]

    # 环境
    def list_containers(self, **kw):        return self._get("/api/v1/container/list", kw)
    def list_running(self):                 return self._get("/api/v1/container/list_running")
    def create_container(self, name, **kw): return self._post("/api/v1/container/create", {"name": name, **kw})
    def update_container(self, id, **kw):   return self._post("/api/v1/container/update", {"id": id, **kw})
    def delete_containers(self, ids):       return self._post("/api/v1/container/delete", {"ids": ids})
    def get_totp(self, id):                 return self._get("/api/v1/container/totp", {"id": id})

    # 浏览器
    def browser_start(self):                return self._get("/api/v1/browser/start")
    def browser_stop(self):                 return self._get("/api/v1/browser/stop")
    def new_tab(self, id, url=None):
        p = {"id": id}
        if url: p["url"] = url
        return self._get("/api/v1/browser/new_tab", p)
    def close_tab(self, id, target_id=None):
        p = {"id": id}
        if target_id: p["target_id"] = target_id
        return self._get("/api/v1/browser/close_tab", p)
    def tab_list(self):                     return self._get("/api/v1/browser/tab_list")

使用示例

from easybrowser_sdk import EasyBrowserAPI

api = EasyBrowserAPI()  # 或 EasyBrowserAPI(api_key="xxx")

# 创建环境
env = api.create_container(name="FB主号", proxy="socks5://u:p@1.2.3.4:1080", tag="Facebook")

# 搜索
result = api.list_containers(name="FB")

# 2FA
totp = api.get_totp(env["id"])
print(f"{totp['code']} ({totp['remaining']}s)")

# 打开环境Tab
api.browser_start()
tab = api.new_tab(env["id"], url="https://facebook.com")

# 查看所有Tab
for t in api.tab_list()["list"]:
    print(f"  {t['container_name']} -> {t['url']}")

# 关闭
api.close_tab(env["id"], tab["target_id"])
api.browser_stop()
api.delete_containers([env["id"]])

Playwright 自动化接管示例

通过 SDK 创建环境、打开 Tab,然后用 Playwright 通过 CDP 接管页面进行自动化操作。

依赖:pip install playwright requests

import asyncio
from easybrowser_sdk import EasyBrowserAPI
from playwright.async_api import async_playwright

api = EasyBrowserAPI()

async def main():
    # 创建环境
    env = api.create_container(
        name="自动化测试",
        proxy="http://user:pass@host:port",
        default_url="https://browserscan.net/"
    )
    env_id = env["id"]

    # 启动浏览器 + 打开 Tab
    debug_port = api.browser_start()["debug_port"]
    target_id = api.new_tab(env_id, url="https://browserscan.net/")["target_id"]
    await asyncio.sleep(3)

    # Playwright 通过 CDP 接管
    async with async_playwright() as p:
        browser = await p.chromium.connect_over_cdp(f"http://127.0.0.1:{debug_port}")

        # 通过 target_id 查找页面
        page = None
        for pg in browser.contexts[0].pages:
            cdp = await browser.contexts[0].new_cdp_session(pg)
            info = await cdp.send("Target.getTargetInfo")
            await cdp.detach()
            if info["targetInfo"]["targetId"] == target_id:
                page = pg
                break

        await page.wait_for_load_state("domcontentloaded")
        print(f"Title: {await page.title()}")
        print(f"URL: {page.url}")

        # 自动化操作...
        # await page.click("button")
        # await page.fill("input", "text")

        await browser.close()

    # 清理
    api.close_tab(env_id, target_id=target_id)
    api.browser_stop()
    api.delete_containers([env_id])

asyncio.run(main())

易语言 SDK + CDP 接管示例

易语言通过 HTTP 调用 Local API 管理环境,通过 WebSocket 发送 CDP 命令控制页面。依赖精易模块。

SDK 核心代码

.版本 2
.程序集 EasyBrowserSDK
.程序集变量 基础地址, 文本型
.程序集变量 API密钥, 文本型

.子程序 初始化, , 公开
.参数 地址, 文本型, 可空
.参数 密钥, 文本型, 可空
.如果 (是否为空 (地址))
    基础地址 = "http://127.0.0.1:50325"
.否则
    基础地址 = 地址
.如果结束
API密钥 = 密钥

.子程序 启动浏览器, 文本型, 公开
返回 (发送GET ("/api/v1/browser/start"))

.子程序 打开Tab, 文本型, 公开
.参数 环境ID, 文本型
.参数 网址, 文本型, 可空
.局部变量 参数, 文本型
参数 = "/api/v1/browser/new_tab?id=" + 环境ID
.如果 (取文本长度 (网址) > 0)
    参数 = 参数 + "&url=" + 编码_URL编码 (网址)
.如果结束
返回 (发送GET (参数))

.子程序 创建环境, 文本型, 公开
.参数 名称, 文本型
.参数 代理, 文本型, 可空
.参数 默认网址, 文本型, 可空
.局部变量 json, 文本型
json = "{" + #引号 + "name" + #引号 + ":" + #引号 + 名称 + #引号
.如果 (取文本长度 (代理) > 0)
    json = json + "," + #引号 + "proxy" + #引号 + ":" + #引号 + 代理 + #引号
.如果结束
.如果 (取文本长度 (默认网址) > 0)
    json = json + "," + #引号 + "defaultUrl" + #引号 + ":" + #引号 + 默认网址 + #引号
.如果结束
json = json + "}"
返回 (发送POST ("/api/v1/container/create", json))

CDP 自动化接管示例

.子程序 _启动子程序, 整数型
.局部变量 返回值, 文本型
.局部变量 环境ID, 文本型
.局部变量 调试端口, 文本型
.局部变量 目标ID, 文本型

' 初始化
初始化 ("http://127.0.0.1:50325", "")

' 创建环境
返回值 = 创建环境 ("易语言测试", "http://user:pass@1.2.3.4:8080", "https://browserscan.net/")
环境ID = JSON解析 (返回值, "data.id")

' 启动浏览器
返回值 = 启动浏览器 ()
调试端口 = JSON解析 (返回值, "data.debug_port")

' 打开Tab
返回值 = 打开Tab (环境ID, "https://browserscan.net/")
目标ID = JSON解析 (返回值, "data.target_id")
延时 (3000)

' ─── CDP 接管:通过 WebSocket 控制页面 ───

' 1. 获取 target 的 WebSocket 地址
.局部变量 targets, 文本型
targets = 网页_访问 ("http://127.0.0.1:" + 调试端口 + "/json")
' 从返回的 JSON 数组中找到 targetId 对应的 webSocketDebuggerUrl
.局部变量 ws地址, 文本型
ws地址 = 解析WS地址 (targets, 目标ID)

' 2. WebSocket 连接
.局部变量 ws, 整数型
ws = WebSocket_创建 ()
WebSocket_连接 (ws, ws地址)

' 3. 获取页面标题
WebSocket_发送 (ws, "{" + #引号 + "id" + #引号 + ":1," + #引号 + "method" + #引号 + ":" + #引号 + "Runtime.evaluate" + #引号 + "," + #引号 + "params" + #引号 + ":{" + #引号 + "expression" + #引号 + ":" + #引号 + "document.title" + #引号 + "}}")
.局部变量 结果, 文本型
结果 = WebSocket_接收 (ws)
调试输出 ("标题: " + JSON解析 (结果, "result.result.value"))

' 4. 获取页面URL
WebSocket_发送 (ws, "{" + #引号 + "id" + #引号 + ":2," + #引号 + "method" + #引号 + ":" + #引号 + "Runtime.evaluate" + #引号 + "," + #引号 + "params" + #引号 + ":{" + #引号 + "expression" + #引号 + ":" + #引号 + "location.href" + #引号 + "}}")
结果 = WebSocket_接收 (ws)
调试输出 ("URL: " + JSON解析 (结果, "result.result.value"))

' 5. 点击元素示例
' WebSocket_发送 (ws, "... Runtime.evaluate ... document.querySelector('button').click() ...")

' 断开
WebSocket_断开 (ws)

' 清理
关闭Tab (环境ID, 目标ID)
关闭浏览器 ()
删除环境 (环境ID)
返回 (0)
EasyBrowser Local API v1.0