一、Open Api本地服务开发指南
1.1 使用方式
- 安装并登录DICloak浏览器
- 打开更多设置 – 开放Api – 获取本地接口URL和密钥
- 获取示例代码,运行脚本

1.2 接口使用概述
- 接口请求方式为post时,传参方式均为body传参,传递json格式数据,不是form-data,也不是url传参数
- 接口请求方式为get时,传参为form-data
- 接口请求方式为put/patch/delete具体传参参考接口文档定义
- 接口请求成功返回200时,返回json对象,code为0作成功,如有返回数据,附加在data对象中
- 接口返回json对象,code为0作成功,如有返回数据,附加在data对象中
- 接口非200时均异常,异常代码参考http错误码,code 不为 0 时,表示失败,失败信息会附加到 msg 字段中,错误码字段参考下表
- 接口所有请求URL均需加上 /openapi,见示例代码
{
'code': 0,
'msg': 'success',
'data': {
'serial_number': 2,
'pid': '27028',
'debug_port': 17539
}
}
{
'code': 500,
'msg': 'fetch fail'
}
- 所有请求都需要加上请求头:
X-API-KEY
,值为从客户端复制出来的密钥
1.3 示例代码
以下demo通过python(playwright)、python(chromedrive)、nodejs(puppeteer)、java(chromedrive)
分别展示了获取环境列表、打开环境、连接环境、操作窗口、关闭页面和窗口等行为;
1.3.1 Python示例代码 (playwright)
import time
import requests
from playwright.sync_api import sync_playwright
# API configuration for DICloak's open API platform
BASE_URL = "http://127.0.0.1:52140/openapi" # Base URL of the API running locally
API_KEY = "*****" # ⚠️ Your API key for authentication
def get_env_list():
"""
Fetch a list of available browser environments from the DICloak API.
Returns a JSON response containing environment details.
"""
headers = {"X-API-KEY": API_KEY} # Set API key in the request headers for authentication
params = {"page_no": 1, "page_size": 20} # Pagination: get first page with up to 20 environments
try:
response = requests.get(f"{BASE_URL}/v1/env/list", params=params, headers=headers)
response.raise_for_status() # Raise an exception for bad HTTP status codes
return response.json() # Return the API response as a Python dictionary
except requests.RequestException as e:
print(f"Failed to fetch environment list: {e}")
return {"code": -1, "msg": str(e)} # Return a mock error response
def open_env(env_id):
"""
Open a specific browser environment using its ID.
Args:
env_id (str): The unique ID of the environment to open.
Returns:
dict: JSON response with details like debug port.
"""
headers = {"X-API-KEY": API_KEY} # Authentication header
try:
response = requests.patch(f"{BASE_URL}/v1/env/{env_id}/open", headers=headers)
response.raise_for_status() # Raise an exception for bad HTTP status codes
return response.json() # Return the response as a dictionary
except requests.RequestException as e:
print(f"Failed to open environment {env_id}: {e}")
return {"code": -1, "msg": str(e)} # Return a mock error response
def close_env(env_id):
"""
Close a specific browser environment using its ID.
Args:
env_id (str): The unique ID of the environment to close.
Returns:
dict: JSON response confirming the closure.
"""
headers = {"X-API-KEY": API_KEY} # Authentication header
try:
response = requests.patch(f"{BASE_URL}/v1/env/{env_id}/close", headers=headers)
response.raise_for_status() # Raise an exception for bad HTTP status codes
return response.json() # Return the response as a dictionary
except requests.RequestException as e:
print(f"Failed to close environment {env_id}: {e}")
return {"code": -1, "msg": str(e)} # Return a mock error response
def get_browser_targets(port):
"""
Get browser connection details (like WebSocket URL) using the debug port.
Args:
port (int): The debug port returned when opening an environment.
Returns:
dict or None: Browser details if successful, None if failed.
"""
url = f"http://127.0.0.1:{port}/json/version" # URL to fetch browser version and WebSocket info
try:
response = requests.get(url)
if response.status_code == 200: # Check if the request was successful
return response.json() # Return browser details
else:
print(f"Failed to get targets: {response.text}") # Print error if request fails
return None
except requests.RequestException as e:
print(f"Failed to get browser targets on port {port}: {e}")
return None
def open_browser_with_playwright(debug_port):
"""
Connect to the browser environment using Playwright and open two web pages.
Args:
debug_port (int): The debug port to connect to the browser.
Returns:
tuple: Playwright instance, browser object, and list of pages (or None if failed).
"""
# Fetch browser connection details using the debug port
targets = get_browser_targets(debug_port)
if targets and 'webSocketDebuggerUrl' in targets: # Check if connection details are valid
ws_url = targets['webSocketDebuggerUrl'] # WebSocket URL to control the browser
print(f"Connecting to WebSocket URL: {ws_url}") # Show the connection URL
try:
# Start Playwright manually (so we can control when to stop it)
p = sync_playwright().start()
browser = p.chromium.connect_over_cdp(ws_url) # Connect to the browser via WebSocket
# Use an existing context if available, or create a new one
context = browser.contexts[0] if browser.contexts else browser.new_context()
# Open Page 1: Visit Zhihu
page1 = context.new_page() # Create a new tab in the browser
page1.goto("https://www.zhihu.com") # Navigate to Zhihu
# Open Page 2: Visit Facebook
page2 = context.new_page() # Create another new tab
page2.goto("https://www.facebook.com") # Navigate to Facebook
# Return Playwright instance, browser, and pages for later use
return p, browser, [page1, page2]
except Exception as e:
print(f"Playwright connection or navigation failed: {e}")
if 'p' in locals(): # Clean up if Playwright was started
p.stop()
return None, None, None
else:
print("No valid WebSocket URL found") # Error message if connection fails
return None, None, None # Return None if something goes wrong
def main():
"""Main function to demonstrate how to use the DICloak API with Playwright."""
try:
# Step 1: Get the list of available environments
resp = get_env_list()
if resp['code'] != 0: # Check if the API call was successful (code 0 means success)
print(f"Error: {resp['msg']}") # Print error message if failed
return
env_list = resp['data']['list'] # Extract the list of environments
if not env_list: # Check if there are any environments available
print("No available environments found")
return
# Step 2: Choose an environment to open (using the second one in the list)
env_id = env_list[1]['id'] # Get the ID of the second environment
print(f"Opening environment: {env_id}") # Show which environment we're opening
# Step 3: Open the environment
open_resp = open_env(env_id)
if open_resp['code'] != 0: # Check if opening was successful
print(f"Error: {open_resp['msg']}")
return
print(f"Environment opened successfully: {open_resp['code'] == 0}")
debug_port = open_resp['data']['debug_port'] # Get the debug port for browser control
print(f"Debug port: {debug_port}")
# Wait for kernel to start
time.sleep(2)
# Step 4: Connect to the browser and open pages
playwright_instance, browser, pages = open_browser_with_playwright(debug_port)
if not browser: # Check if connection failed
print("Failed to connect to the browser")
return
# Step 5: Wait and close Page 1
print("Waiting 5 seconds before closing Page 1")
time.sleep(5)
try:
pages[0].close() # Close the first page (Zhihu)
print("Page 1 closed")
except Exception as e:
print(f"Failed to close Page 1: {e}")
# Step 6: Wait and close the environment
print("Waiting 5 seconds before closing the environment")
time.sleep(5)
try:
close_env(env_id) # Close the environment via API
browser.close() # Close the browser connection
playwright_instance.stop() # Stop Playwright and free resources
print("Environment closed and resources freed")
except Exception as e:
print(f"Failed to clean up resources: {e}")
except Exception as e:
print(f"Unexpected error in main: {e}")
if __name__ == "__main__":
main() # Run the main function when the script is executed
1.3.2 Python示例代码
DICloak内核用的是120内核,需要先下载 chromedriver:
import time
import requests
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
# API configuration
BASE_URL = "http://127.0.0.1:52140/openapi" # API base URL
API_KEY = "*****" # ⚠️ Your API key for authentication
def open_browser(port):
"""
Connect to a browser using Selenium and open a webpage.
:param port: Debug port to connect to the browser.
"""
chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option('debuggerAddress', f"127.0.0.1:{port}") # Use debug port
s = Service(r"G:\chromedriver.exe") # Path to ChromeDriver
browser = webdriver.Chrome(options=chrome_options, service=s)
browser.get("https://www.facebook.com") # Open Facebook as an example
def get_evn_list():
# Get list of available environments from the API
headers = {"X-API-KEY": API_KEY} # Authentication header
params = {"page_no": 1, "page_size": 20} # Pagination settings
response = requests.get(f"{BASE_URL}/v1/env/list", params=params, headers=headers)
return response.json()
def open_env(env_id):
"""
Open an environment by ID.
:param env_id: The ID of the environment to open.
"""
headers = {"X-API-KEY": API_KEY} # Authentication header
response = requests.patch(f"{BASE_URL}/v1/env/{env_id}/open", headers=headers)
return response.json()
def close_env(env_id):
"""
Close an environment by ID.
:param env_id: The ID of the environment to close.
"""
headers = {"X-API-KEY": API_KEY} # Authentication header
response = requests.patch(f"{BASE_URL}/v1/env/{env_id}/close", headers=headers)
return response.json()
if __name__ == '__main__':
# Get environment list
resp = get_evn_list()
if resp['code'] != 0: # Check for errors
print(resp.msg)
exit(0)
list = resp['data']['list'] # Extract environment list
if len(list) == 0: # Check if list is empty
print('no profile')
exit(0)
print(f"open profile:{list[0]['id']}") # Show the ID of the first environment
# Open the environment
open_resp = open_env(list[0]['id'])
if open_resp['code'] != 0: # Check for errors
print(open_resp['msg'])
exit(0)
print(f"open_resp : {open_resp}") # Show response details
# Connect to browser and open a page
open_browser(open_resp['data']['debug_port'])
time.sleep(3) # Wait 3 seconds
# Close the environment
close_env(list[0]['id'])
1.3.3 Node.js 示例代码 (puppeteer)
const puppeteer = require('puppeteer');
const axios = require('axios');
// API configuration for DICloak's open API platform
const BASE_URL = "http://127.0.0.1:52140/openapi"; // Base URL of the API running locally
const API_KEY = "*****"; // Your API key for authentication
async function getEnvList() {
/**
* Fetch a list of available browser environments from the DICloak API.
* Returns a JSON response with environment details.
*/
const headers = { "X-API-KEY": API_KEY }; // Set API key for authentication
const params = { page_no: 1, page_size: 20 }; // Pagination: get first page with up to 20 environments
try {
const response = await axios.get(`${BASE_URL}/v1/env/list`, { params, headers });
return response.data; // Return the API response as an object
} catch (error) {
console.log(`Failed to fetch environment list: ${error.message}`);
return { code: -1, msg: error.message }; // Return a mock error response
}
}
async function openEnv(envId) {
/**
* Open a specific browser environment using its ID.
* @param {string} envId - The unique ID of the environment to open.
* @returns {object} - JSON response with details like debug port.
*/
const headers = { "X-API-KEY": API_KEY }; // Authentication header
try {
const response = await axios.patch(`${BASE_URL}/v1/env/${envId}/open`, {}, { headers });
return response.data; // Return the response as an object
} catch (error) {
console.log(`Failed to open environment ${envId}: ${error.message}`);
return { code: -1, msg: error.message }; // Return a mock error response
}
}
async function closeEnv(envId) {
/**
* Close a specific browser environment using its ID.
* @param {string} envId - The unique ID of the environment to close.
* @returns {object} - JSON response confirming the closure.
*/
const headers = { "X-API-KEY": API_KEY }; // Authentication header
try {
const response = await axios.patch(`${BASE_URL}/v1/env/${envId}/close`, {}, { headers });
return response.data; // Return the response as an object
} catch (error) {
console.log(`Failed to close environment ${envId}: ${error.message}`);
return { code: -1, msg: error.message }; // Return a mock error response
}
}
async function getBrowserTargets(port) {
/**
* Get browser connection details (like WebSocket URL) using the debug port.
* @param {number} port - The debug port returned when opening an environment.
* @returns {object|null} - Browser details if successful, null if failed.
*/
const url = `http://127.0.0.1:${port}/json/version`; // URL to fetch browser version and WebSocket info
try {
const response = await axios.get(url);
return response.data; // Return browser details
} catch (error) {
console.log(`Failed to get targets: ${error.message}`); // Print error if request fails
return null;
}
}
async function openBrowserWithPuppeteer(debugPort) {
/**
* Connect to the browser environment using Puppeteer and open two web pages.
* @param {number} debugPort - The debug port to connect to the browser.
* @returns {Promise<object>} - Puppeteer browser object and list of pages (or null if failed).
*/
// Fetch browser connection details using the debug port
const targets = await getBrowserTargets(debugPort);
if (targets && targets.webSocketDebuggerUrl) { // Check if connection details are valid
const wsUrl = targets.webSocketDebuggerUrl; // WebSocket URL to control the browser
console.log(`Connecting to WebSocket URL: ${wsUrl}`); // Show the connection URL
try {
// Connect to the existing browser instance via WebSocket
const browser = await puppeteer.connect({
browserWSEndpoint: wsUrl, // Use the WebSocket URL from the API
defaultViewport: null // Keep the default viewport of the environment
});
// Open Page 1: Visit Zhihu
const page1 = await browser.newPage(); // Create a new tab in the browser
await page1.goto("https://www.zhihu.com"); // Navigate to Zhihu
// Open Page 2: Visit Baidu
const page2 = await browser.newPage(); // Create another new tab
await page2.goto("https://www.baidu.com"); // Navigate to Baidu
// Return browser and pages for later use
return { browser, pages: [page1, page2] };
} catch (error) {
console.log(`Puppeteer connection or navigation failed: ${error.message}`);
return null; // Return null if something goes wrong
}
} else {
console.log("No valid WebSocket URL found"); // Error message if connection fails
return null; // Return null if something goes wrong
}
}
async function main() {
/** Main function to demonstrate how to use the DICloak API with Puppeteer. */
try {
// Step 1: Get the list of available environments
const resp = await getEnvList();
if (resp.code !== 0) { // Check if the API call was successful (code 0 means success)
console.log(`Error: ${resp.msg}`); // Print error message if failed
return;
}
const envList = resp.data.list; // Extract the list of environments
if (!envList || envList.length === 0) { // Check if there are any environments available
console.log("No available environments found");
return;
}
// Step 2: Choose an environment to open (using the second one in the list)
const envId = envList[1].id; // Get the ID of the second environment
console.log(`Opening environment: ${envId}`); // Show which environment we're opening
// Step 3: Open the environment
const openResp = await openEnv(envId);
if (openResp.code !== 0) { // Check if opening was successful
console.log(`Error: ${openResp.msg}`);
return;
}
console.log(`Environment opened successfully: ${openResp.code === 0}`);
const debugPort = openResp.data.debug_port; // Get the debug port for browser control
console.log(`Debug port: ${debugPort}`);
// Wait for kernel to start
await new Promise((resolve) => setTimeout(() => {
resolve()
}, 2000))
// Step 4: Connect to the browser and open pages
const result = await openBrowserWithPuppeteer(debugPort);
if (!result) { // Check if connection failed
console.log("Failed to connect to the browser");
return;
}
const { browser, pages } = result;
// Step 5: Wait and close Page 1
console.log("Waiting 5 seconds before closing Page 1");
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
try {
await pages[0].close(); // Close the first page (Zhihu)
console.log("Page 1 closed");
} catch (error) {
console.log(`Failed to close Page 1: ${error.message}`);
}
// Step 6: Wait and close the environment
console.log("Waiting 5 seconds before closing the environment");
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
try {
await closeEnv(envId); // Close the environment via API
await browser.close(); // Close the browser connection
console.log("Environment closed and resources freed");
} catch (error) {
console.log(`Failed to clean up resources: ${error.message}`);
}
} catch (error) {
console.error(`Unexpected error in main: ${error.message}`);
}
}
// Run the main function and handle any errors
main().catch(error => {
console.error(`An error occurred: ${error.message}`);
process.exit(1); // Exit with an error code if something goes wrong
});
1.3.4 java示例代码
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
import org.json.JSONArray;
import org.json.JSONObject;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class Main {
// API configuration
private static final String BASE_URL = "http://127.0.0.1:52140/openapi"; // Base URL for the DICloak API
private static final String API_KEY = "****"; // ⚠️ Your API key for authentication
public static void main(String[] args) {
// Get environment list
JSONObject resp = getEvnList();
if (resp.getInt("code") != 0) { // Check for errors
System.out.println(resp.getString("msg"));
System.exit(0);
}
JSONArray list = resp.getJSONObject("data").getJSONArray("list"); // Extract environment list
if (list.length() == 0) { // Check if list is empty
System.out.println("no profile");
System.exit(0);
}
System.out.println("open profile:" + list.getJSONObject(0).getString("id")); // Show first environment ID
// Open the environment
JSONObject openResp = openEnv(list.getJSONObject(0).getString("id"));
if (openResp.getInt("code") != 0) { // Check for errors
System.out.println(openResp.getString("msg"));
System.exit(0);
}
System.out.println("open_resp : " + openResp); // Show response details
// Open browser and visit a webpage
WebDriver browser = openBrowser(openResp.getJSONObject("data").getString("debug_port"));
try {
TimeUnit.SECONDS.sleep(3); // Wait 3 seconds
} catch (InterruptedException e) {
e.printStackTrace(); // Print error if sleep is interrupted
}
// Close the environment
closeEnv(list.getJSONObject(0).getString("id"));
// Close the browser
browser.quit();
}
public static JSONObject getEvnList() {
// Fetch list of environments from the API
try {
URL url = new URL(BASE_URL + "/v1/env/list?page_no=1&page_size=20"); // API endpoint with pagination
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("X-API-KEY", API_KEY); // Set API key header
connection.setRequestMethod("GET"); // Use GET method
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { // Check if request succeeded
Scanner scanner = new Scanner(connection.getInputStream());
StringBuilder response = new StringBuilder();
while (scanner.hasNextLine()) {
response.append(scanner.nextLine());
}
scanner.close();
return new JSONObject(response.toString()); // Return JSON response
}
throw new RuntimeException("Request failed, status code: " + responseCode);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static JSONObject openEnv(String envId) {
// Open an environment by ID
try {
URL url = new URL(BASE_URL + "/v1/env/" + envId + "/open"); // API endpoint to open environment
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("X-API-KEY", API_KEY); // Set API key header
connection.setRequestMethod("PATCH"); // Use PATCH method
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { // Check if request succeeded
Scanner scanner = new Scanner(connection.getInputStream());
StringBuilder response = new StringBuilder();
while (scanner.hasNextLine()) {
response.append(scanner.nextLine());
}
scanner.close();
return new JSONObject(response.toString()); // Return JSON response
}
throw new RuntimeException("Request failed, status code: " + responseCode);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static JSONObject closeEnv(String envId) {
// Close an environment by ID
try {
URL url = new URL(BASE_URL + "/v1/env/" + envId + "/close"); // API endpoint to close environment
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("X-API-KEY", API_KEY); // Set API key header
connection.setRequestMethod("PATCH"); // Use PATCH method
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { // Check if request succeeded
Scanner scanner = new Scanner(connection.getInputStream());
StringBuilder response = new StringBuilder();
while (scanner.hasNextLine()) {
response.append(scanner.nextLine());
}
scanner.close();
return new JSONObject(response.toString()); // Return JSON response
}
throw new RuntimeException("Request failed, status code: " + responseCode);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static WebDriver openBrowser(String port) {
// Connect to browser using Selenium and debug port
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setExperimentalOption("debuggerAddress", "127.0.0.1:" + port); // Use debug port
return new ChromeDriver(chromeOptions); // Launch Chrome browser
}
}