Open API
很多同学希望能够通过程序/脚本控制花漾客户端,如:通过程序/脚本访问某个账号以打开/关闭花漾指纹浏览器等,从而方便与其它系统的整合。 基于此,花漾提供了Open API的特性,其实现原理是基于Access Key认证体系的Http请求/响应机制,理论上允许用户使用任意语言如Java、Python、C# 等与花漾客户端进行交互。
1、开启 Open API 选项并获得 Access Key
在使用 Open API 之前,首先需要开启API,请切换至“团队”主页签,并在“团队资源”处,开启 Open API:

《在团队资源中开启Open API》
当 Open API 开启后,可以点击“新增”按钮,创建一个新的 Access Key,请注意,每一个Access Key都需要指定一个用户身份, 换言之,当您使用某个Access Key并通过 Open API 来操纵花漾客户端时,本质上相当于使用与此Access Key绑定的用户身份进行的操作:

《创建 Access Key》
需要提醒您的是,生成的 Access Key 请务必妥善保存,以避免造成信息安全风险。
2、花漾 Open API 参考指引
目前花漾 Open API 仅提供了一些有限的接口列表,主要包括查询 RPA 任务详情、打开/关闭某个账号对应的浏览器等等。 目前花漾已经开放的API列表请参考:https://app.szdamai.com/open-api/ 。 需要提醒您的是,上述API参考既是一个在线文档,同时也是花漾 Open API 的调试工具,关于其更详细的介绍,请参考 API参考及Swagger在线调试工具。
3、花漾 Open API 的调用
3.1 调用端点(Endpoint)与时间格式
花漾Open API的调用端点(Endpoint)是:https://api.szdamai.com/openapi/; 输入/输出的时间格式是:"yyyy-MM-dd'T'HH:mm:ss'Z'",采用UTC+0时区。举例,当输出"2022-09-05T11:12:28Z"时, 代表东8区(北京时间)的2022-09-05 19:12:28。
3.2 认证方式
目前仅支持OAuth Token的方式进行校验,即客户使用 AccessKeyId + AccessKeySecret,跟 Endpoint 换取一个 Token, 在后续请求中,把 Token 放入http头中:'Authorization: YOUR_Token',后续所有请求将以 Access Key 代表的用户身份进行操作。
以下举例说明:
curl -X 'GET' 'https://api.szdamai.com/openapi/token?accessKeyId=YOUR_AccessKeyId&accessKeySecret=YOUR_AccessKeySecret&expireSeconds=7200' -H 'accept: */*
其中 expireSeconds 是 Token 超时时间,单位:秒,取值范围为[120,7200];当Token超时以后,请求会失败, 建议您在Token超时之前重新获取Token。
上述http请求的返回结果如下所示:
{
"success": true, "code": 0, "message": null,
"data": {
"token": "eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJ0b2MiLCJqdGkiOiI2MTY1ODY4MjEyMWI0NzQ1OTNmZDBjYzVjYzAzOTk1NyIsInN1YiI6IkFLLUFLUVpQY3Z4YVRsMU85bkwwUUhjSHp0IiwiZXhwIjoxNjYyMzc2MzQ4fQ.TjG0VLwNrJrn8-XyxHz-OfhNjlLkalan3EBr92cdKc8GGaKwFNEqUpBInKiUJ6ixybIpKnYNpsjxktliw2nIbjYgTnCRbT1G7jHogx2Y_7eDigJjyrpyZwdlZ5ZEGHPn01fNWFS0RkgHqeraQoNwbgVDU3T2rbJfZtG3W5vGuhRrmYaC-_pXjkvWhXgc4ZkIDV7j-364hyyZXM9W326iIoW9aaj1BhAWuttdXt-sl8aEDsbESEZxCziBE6_Q_MdJ4BvBi8yGp9M2yhjlkh2pNjF_nkl68QwVpsR8HW--2jTwjZLdHhsOl45Fp55ELV_y8czLUuo0-X5Sp6443UBXGA",
"expireTime": "2022-09-05T11:12:28Z"
}
}
其中,那一长串基于Base64编码的字符串,就是认证Token,而 expireTime 则是此Token的超时时间。
当认证成功获得 Token 后,我们就可以将 Token 放入到 Http头中,以调用花漾 Open API 了。
我们以查看当前用户信息这个 API 接口为例, 请求内容如下:
curl -X 'GET' 'https://api.szdamai.com/openapi/user/current' -H 'accept: */*'
-H 'Authorization: eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJ0b2MiLCJqdGkiOiI2MTY1ODY4MjEyMWI0NzQ1OTNmZDBjYzVjYzAzOTk1NyIsInN1YiI6IkFLLUFLUVpQY3Z4YVRsMU85bkwwUUhjSHp0IiwiZXhwIjoxNjYyMzc2MzQ4fQ.TjG0VLwNrJrn8-XyxHz-OfhNjlLkalan3EBr92cdKc8GGaKwFNEqUpBInKiUJ6ixybIpKnYNpsjxktliw2nIbjYgTnCRbT1G7jHogx2Y_7eDigJjyrpyZwdlZ5ZEGHPn01fNWFS0RkgHqeraQoNwbgVDU3T2rbJfZtG3W5vGuhRrmYaC-_pXjkvWhXgc4ZkIDV7j-364hyyZXM9W326iIoW9aaj1BhAWuttdXt-sl8aEDsbESEZxCziBE6_Q_MdJ4BvBi8yGp9M2yhjlkh2pNjF_nkl68QwVpsR8HW--2jTwjZLdHhsOl45Fp55ELV_y8czLUuo0-X5Sp6443UBXGA'
返回结果如下所示:
{
"success": true,
"code": 0,
"message": null,
"data": {
"id": 52394196996096,
"tenant": null,
"status": "ACTIVE",
"nickname": "子非鱼",
"createTime": "2021-08-27T07:02:51Z",
"avatar": null,
"gender": "UNSPECIFIC",
"signature": "",
"residentCity": "",
"userType": "NORMAL",
"partnerId": null,
"phone": "186****2179",
"email": "c****u@1*6.com",
"weixin": null
}
}
我们可以看到,通过 “https://api.szdamai.com/openapi/user/current” 接口能够成功查询当前用户的基本信息。
综上,我们已经完整的了解了如何通过Access Key获得认证Token,以及将Token放入到http头中以调用 Open API, 再通过参考花漾目前公开的API列表,理论上您可以通过任何语言/脚本来和花漾客户端进行交互了。
4、示例
4.1 通过Java调用花漾Open API
我们为您准备了一个简单的基于Java语言的示例程序,如下所示:
package com.donkey.openapi.example;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
public class BasicHttpClientDemo {
static String accessKeyId = "REPLACE_WITH_YOUR_AKID";
static String accessKeySecret = "REPLACE_WITH_YOUR_AKSECRET";
static String endpoint = "https://api.szdamai.com/openapi";
public static void main(String[] args) throws IOException {
//获取认证token
Map<String, Object> resp = request("GET",
String.format("/token?accessKeyId=%s&accessKeySecret=%s&expireSeconds=%d", accessKeyId, accessKeySecret, 7200), null);
String token = (String) resp.get("token");
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", token);
//请求当前用户信息
Map<String, Object> userObj = request("GET", "/user/current", headers);
System.out.println(userObj);
}
public static Map<String, Object> request(String method, String path, Map<String, String> headers) throws IOException {
URL url = new URL(endpoint + path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(method);
if (headers != null) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
conn.setRequestProperty(entry.getKey(), entry.getValue());
}
}
try {
conn.connect();
if (200 <= conn.getResponseCode() && conn.getResponseCode() < 300) {
String responseJson = copy2String(conn.getInputStream());
Map<String, Object> resp = JsonHelper.jsonDecode(responseJson);
if (Boolean.TRUE.equals(resp.get("success"))) {
return (Map<String, Object>) resp.get("data");
} else {
String msg = (String) resp.get("message");
if (msg == null) {
msg = conn.getResponseMessage();
}
throw new IOException("access openapi error :" + msg);
}
} else {
throw new IOException("access openapi error :" + conn.getResponseCode() + " - " + conn.getResponseMessage());
}
} finally {
conn.disconnect();
}
}
public static String copy2String(InputStream inStream) throws IOException {
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inStream.read(buffer)) != -1) {
result.write(buffer, 0, len);
}
String str = result.toString(StandardCharsets.UTF_8.name());
return str;
}
}
如有需要,您可以下载 Demo程序的源码 。
4.2 通过Python调用花漾Open API
同时,我们也为您准备了一个简单的基于Python语言的示例程序,如下所示:
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import re
import sys
import requests
import json
import os
apiEndpoint = "https://api.szdamai.com/openapi"
'''
openApi: function to access api url and post parameters
'''
def openApi(url: str, params: dict = None, headers: dict = None, method: str = "GET", contentType: str = "json", timeout: int = 10) -> dict:
if method == "GET":
response = requests.get(apiEndpoint + url, params=params, headers=headers, timeout=timeout)
elif method == "POST":
if not headers:
headers = dict()
if contentType == "json":
headers["Content-Type"] = "application/json"
params = json.dumps(params) if params else None
response = requests.post(apiEndpoint + url, data=params, headers=headers, timeout=timeout)
elif method == "DELETE":
response = requests.delete(apiEndpoint + url, data=params, headers=headers, timeout=timeout)
else:
return None
if not response:
return None
if not 200 <= response.status_code <= 299:
return None
result=json.loads(response.text)
if result["success"]:
return result["data"]
else:
print("openApi %s error %s"%(url,result["message"]))
return None
def getToken(accessKeyId, accessKeySecret, expireSeconds=300):
tokenJson = openApi(
"/token",
params={
"accessKeyId": accessKeyId,
"accessKeySecret": accessKeySecret,
"expireSeconds": expireSeconds
},
)
return tokenJson["token"]
def getCurrentUser(token):
hostJson = openApi(
"/user/current",
params={},
headers={"Authorization": token}
)
return hostJson
def main(args, **kwargs):
accessKeyId =args[0]
accessKeySecret =args[1]
if not accessKeyId or not accessKeySecret:
print("AccessKeyId and AccessKeySecret are not present.\n")
return -1
token = getToken(accessKeyId, accessKeySecret)
if not token:
print("Invalid AccessKeyId and AccessKeySecret.\n")
return -1
user = getCurrentUser(token=token)
if user:
print("Current user is %s.\n" % (user))
else:
print("get Current user fail\n")
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: openapi_demo.py AccessKeyId AccessKeySecret\n")
sys.exit(-1)
sys.exit(main(sys.argv[1:3], **dict(arg.split('=') for arg in sys.argv[4:])))
如有需要,您可以点这里下载 Demo程序的源码 。
4.3 通过Python调用花漾Open API打开浏览器分身后使用selenium控制浏览器
在4.2 Python示例程序的基础上,您可以通过调用花漾Open API打开浏览器分身,并使用selenium进行控制。 这里有几点需要注意:
- 可以通过api指定控制端口,比如下面的程序中指定的控制端口是9222;
- 可以通过api的browserSwitches参数指定启动浏览器的参数;
- accountId指的是分身ID,获取方式见 这里 ;
- 需要在本地准备好对应版本的chromedriver,您可以这里下载 chromedriver ,或者直接使用我们提供的 chromedriver 。
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from time import sleep
# 示例代码中用的selenium是3.141.0
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import sys
import requests
import json
apiEndpoint = "https://api.szdamai.com/openapi"
'''
openApi: function to access api url and post parameters
'''
def openApi(url: str, params: dict = None, headers: dict = None, method: str = "GET", contentType: str = "json", timeout: int = 10) -> dict:
if method == "GET":
response = requests.get(
apiEndpoint + url, params=params, headers=headers, timeout=timeout)
elif method == "POST":
if not headers:
headers = dict()
if contentType == "json":
headers["Content-Type"] = "application/json"
params = json.dumps(params) if params else None
response = requests.post(
apiEndpoint + url, data=params, headers=headers, timeout=timeout)
elif method == "DELETE":
response = requests.delete(
apiEndpoint + url, data=params, headers=headers, timeout=timeout)
else:
return None
if not response:
return None
if not 200 <= response.status_code <= 299:
return None
result = json.loads(response.text)
if result["success"]:
return result["data"]
else:
print("openApi %s error %s" % (url, result["message"]))
return None
def getToken(accessKeyId, accessKeySecret, expireSeconds=300):
tokenJson = openApi(
"/token",
params={
"accessKeyId": accessKeyId,
"accessKeySecret": accessKeySecret,
"expireSeconds": expireSeconds
},
)
return tokenJson["token"]
def getCurrentUser(token):
hostJson = openApi(
"/user/current",
params={},
headers={"Authorization": token}
)
return hostJson
def openSession(token, accountId):
browserSwitches = "--window-size=700,600\n--window-position=100,50"
hostJson = openApi(
"/session/openV2",
params={
"accountId": accountId,
"remoteDebugPort": 9222,
"browserSwitches": browserSwitches,
},
method="POST",
headers={"Authorization": token}
)
return hostJson
def useSelenium():
chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
# chromedriver.exe可以在这里下载,必须是对应花漾的内核版本:
# http://chromedriver.storage.googleapis.com/index.html?path=111.0.5563.41/
driver = webdriver.Chrome('d:/chromedriver.exe', options=chrome_options)
# 打开网站
driver.get('https://www.baidu.com') # 指定要打开的网站 URL
sleep(1)
print(driver.title)
def main(args, **kwargs):
accessKeyId = args[0]
accessKeySecret = args[1]
accountId = args[2]
if not accessKeyId or not accessKeySecret:
print("AccessKeyId and AccessKeySecret are not present.\n")
return -1
token = getToken(accessKeyId, accessKeySecret)
if not token:
print("Invalid AccessKeyId and AccessKeySecret.\n")
return -1
user = getCurrentUser(token=token)
if user:
print("Current user is %s.\n" % (user))
rs = openSession(token, accountId)
print(rs)
sleep(10)
useSelenium()
else:
print("get Current user fail\n")
if __name__ == "__main__":
if len(sys.argv) != 4:
print("Usage: python SeleniumTest.py AccessKeyId AccessKeySecret accountId\n")
sys.exit(-1)
sys.exit(main(sys.argv[1:4], **dict(arg.split('=')
for arg in sys.argv[5:])))
如有需要,您可以点这里下载 Demo程序的源码 。
4.4 其它
如果您有新的 API 方面的诉求,或者还希望我们提供其它语言的的Demo,请通过在 在线客服 联络我们。