Local API 文档
通过本地 HTTP 接口自动化管理环境与浏览器。
架构说明
EasyBrowser 采用单浏览器实例 + 多 Tab 环境隔离架构:
- 只运行一个浏览器进程,节省资源
- 每个环境 = 一个独立隔离 Tab
- Tab 间指纹、Cookie、存储完全隔离
browser/start启动进程,new_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"
}| 字段 | 说明 |
|---|---|
| 账户邮箱 | |
| 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"
}| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 环境唯一ID(UUID) |
| name | string | 环境名称 |
| proxy | string|null | 代理地址 protocol://user:pass@host:port |
| tag | string|null | 标签/分组 |
| defaultUrl | string|null | 启动时默认打开的URL |
| account | string|null | 平台账号 |
| twofa_secret | string|null | TOTP 2FA 密钥(Base32) |
| notes | string|null | 备注 |
| created_at | number | 创建时间(Unix时间戳,秒) |
| last_opened | number|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 | 是 | 环境名称 |
| proxy | 否 | protocol://user:pass@host:port |
| tag | 否 | 标签 |
| defaultUrl | 否 | 默认打开URL |
| account | 否 | 账号 |
| password | 否 | 密码 |
| twofa_secret | 否 | 2FA密钥(Base32) |
| notes | 否 | 备注 |
| cookie | 否 | Cookie 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" }| 字段 | 说明 |
|---|---|
| code | 6位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_id | Tab唯一标识,可用于 close_tab 和 CDP 连接 |
关闭Tab
GET/api/v1/browser/close_tab
参数
| 参数 | 必需 | 说明 |
|---|---|---|
| id | 是 | 环境ID |
| target_id | 否 | Tab 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_id | Tab唯一标识 |
| url | Tab当前访问的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