Skip to content
Home » DICloak API开发指南

DICloak API开发指南

  • by

一、Open Api本地服务开发指南

1.1 使用方式

  1. 安装并登录DICloak浏览器
  2. 打开更多设置 – 开放Api – 获取本地接口URL和密钥
  3. 获取示例代码,运行脚本

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
    }
}