在影刀中做了很多应用,有些分享出去了,想了解分享出去后的使用情况。影刀企业版有控制台,可以查看数据。对于免费版就没这方面功能了。
有影刀社区中,有刀友建议在应用中添加钉钉或飞书发信息的方式,获取统计数据。我是通过钉钉集中获取应用报错信息的,如果再添加统计数据发送,假如应用运行的次数多,那一定很烦,且这个方式并不适合做统计汇总。
碰巧我有一个使用Wordpress搭建的个人网站,就想到了这个办法,借用Wordpress的REST API和自定义数据库存储能力,结合影刀的Python 代码节点,来实现精准统计应用运行次数和时长的需求。
如果你碰巧也有Wordpress网站,那可以直接尝试我这个方法。
如果你没有Wordpress网站,也可以参考我的思路或逻辑,比如将数据发送写入到自己的MySQL数据库中,后续再进行查询。
先看一下测试的效果展示:

核心逻辑
影刀每次运行时,通过代码节点向 WordPress 发送运行数据;WordPress 接收数据后存入数据库,最后通过自定义页面 / 短代码展示统计结果。
操作步骤
- WordPress添加自定义插件
3.1 在电脑上新建一个文本文件,重命名为 rpa-stat.php。将以下代码完整复制进去:
<?php
/*
Plugin Name: RPA 运行监控中心 (Pro版)
Description: 接收影刀 RPA 上报的数据,支持记录应用名称、IP、状态及运行时长。
Version: 2.0
Author: RPA Monitor
*/
// 1. 初始化数据库表 (增加 app_name 和 user_ip 字段)
function rpa_stat_create_table_pro() {
global $wpdb;
$table_name = $wpdb->prefix . 'rpa_run_stats';
$charset_collate = $wpdb->get_charset_collate();
// SQL 语句:自动创建或升级表结构
$sql = "CREATE TABLE $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
app_key varchar(50) NOT NULL COMMENT '应用唯一标识',
app_name varchar(100) NOT NULL COMMENT '应用显示名称',
start_time datetime NOT NULL COMMENT '开始时间',
end_time datetime NOT NULL COMMENT '结束时间',
duration float NOT NULL COMMENT '运行时长(秒)',
status varchar(20) DEFAULT 'success' COMMENT '运行状态',
user_ip varchar(45) DEFAULT '' COMMENT '运行机器IP',
create_time datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY app_key (app_key)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
// 插件激活时运行建表逻辑
register_activation_hook(__FILE__, 'rpa_stat_create_table_pro');
// 为了确保新字段生效,我们挂载到 plugins_loaded 再次检查结构
add_action('plugins_loaded', 'rpa_stat_create_table_pro');
// 2. 注册 REST API 接口
add_action('rest_api_init', function () {
register_rest_route('rpa-stat/v1', '/report', array(
'methods' => 'POST',
'callback' => 'rpa_stat_handle_request',
'permission_callback' => '__return_true', // 使用自定义密钥验证
));
});
function rpa_stat_handle_request($request) {
global $wpdb;
$table_name = $wpdb->prefix . 'rpa_run_stats';
$params = $request->get_json_params();
// --- 安全验证 ---
$secret_key = 'your_secure_secret_123456'; // 【请修改】必须与影刀中一致
if (!isset($params['secret_key']) || $params['secret_key'] !== $secret_key) {
return new WP_Error('403', '非法访问:密钥错误', array('status' => 403));
}
// --- 获取真实 IP ---
$user_ip = $_SERVER['REMOTE_ADDR'];
// 如果使用了 CDN (如 Cloudflare),尝试获取真实 IP
if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
$user_ip = $_SERVER["HTTP_CF_CONNECTING_IP"];
} elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$user_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
// --- 写入数据库 ---
$result = $wpdb->insert(
$table_name,
array(
'app_key' => sanitize_text_field($params['app_key']),
'app_name' => sanitize_text_field($params['app_name']), // 新增字段
'start_time' => sanitize_text_field($params['start_time']),
'end_time' => sanitize_text_field($params['end_time']),
'duration' => floatval($params['duration']),
'status' => sanitize_text_field($params['status']),
'user_ip' => sanitize_text_field($user_ip) // 新增字段
),
array('%s', '%s', '%s', '%s', '%f', '%s', '%s')
);
if ($result) {
return array('success' => true, 'id' => $wpdb->insert_id, 'ip_recorded' => $user_ip);
} else {
return new WP_Error('500', '数据库写入失败', array('status' => 500));
}
}
// 3. 短代码展示 (前端仪表盘)
add_shortcode('rpa_stat', 'rpa_stat_render_dashboard');
function rpa_stat_render_dashboard($atts) {
global $wpdb;
$table_name = $wpdb->prefix . 'rpa_run_stats';
// 筛选参数:[rpa_stat app_key="xxx"]
$atts = shortcode_atts(array('app_key' => ''), $atts);
$where = "";
if ($atts['app_key']) {
$where = $wpdb->prepare("WHERE app_key = %s", $atts['app_key']);
}
// 数据查询
$total_runs = $wpdb->get_var("SELECT COUNT(*) FROM $table_name $where");
$total_duration = $wpdb->get_var("SELECT SUM(duration) FROM $table_name $where");
$fail_count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name $where AND status = 'failed'");
$logs = $wpdb->get_results("SELECT * FROM $table_name $where ORDER BY start_time DESC LIMIT 20");
// 计算展示数据
$hours = $total_duration ? round($total_duration / 3600, 2) : 0;
$success_rate = $total_runs > 0 ? round((($total_runs - $fail_count) / $total_runs) * 100, 1) : 0;
// 内联样式与 HTML
$html = '<style>
.rpa-dashboard { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; max-width: 100%; overflow-x: auto; }
.rpa-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); gap: 15px; margin-bottom: 20px; }
.rpa-card { background: #fff; padding: 15px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.05); text-align: center; border: 1px solid #eee; }
.rpa-card h4 { margin: 0 0 5px; font-size: 12px; color: #666; font-weight: normal; }
.rpa-card .num { font-size: 24px; font-weight: bold; color: #2271b1; }
.rpa-table { width: 100%; border-collapse: collapse; font-size: 13px; background: #fff; }
.rpa-table th { background: #f0f0f1; text-align: left; padding: 10px; border-bottom: 2px solid #ddd; }
.rpa-table td { padding: 8px 10px; border-bottom: 1px solid #eee; color: #555; }
.status-tag { padding: 2px 6px; border-radius: 4px; font-size: 11px; font-weight: bold; }
.st-success { background: #d1e7dd; color: #0f5132; }
.st-failed { background: #f8d7da; color: #842029; }
.ip-addr { font-family: monospace; color: #888; }
</style>';
$html .= '<div class="rpa-dashboard">';
$html .= '<div class="rpa-cards">
<div class="rpa-card"><h4>总运行次数</h4><div class="num">'.$total_runs.'</div></div>
<div class="rpa-card"><h4>总时长(小时)</h4><div class="num">'.$hours.'</div></div>
<div class="rpa-card"><h4>成功率</h4><div class="num">'.$success_rate.'%</div></div>
</div>';
$html .= '<table class="rpa-table"><thead>
<tr>
<th>状态</th>
<th>应用名称</th>
<th>开始时间</th>
<th>时长(秒)</th>
<th>运行IP</th>
</tr>
</thead><tbody>';
foreach ($logs as $log) {
$st_class = ($log->status == 'success') ? 'st-success' : 'st-failed';
$st_text = ($log->status == 'success') ? '成功' : '失败';
$html .= "<tr>
<td><span class='status-tag {$st_class}'>{$st_text}</span></td>
<td><strong>{$log->app_name}</strong><br><small style='color:#999'>{$log->app_key}</small></td>
<td>{$log->start_time}</td>
<td>{$log->duration}</td>
<td class='ip-addr'>{$log->user_ip}</td>
</tr>";
}
$html .= '</tbody></table></div>';
return $html;
}
注意:替换53行代码中的秘钥'your_secure_secret_123456'为自己设置的复杂秘钥,注意和影刀中的保持一致。
3.2 将 `rpa-stat.php` 放入文件夹 `rpa-stat` 中。 3.3 将文件夹上传到 WordPress 的 `wp-content/plugins/` 目录。

3.4 进入 WordPress 后台 -> 插件 -> 启用 RPA 运行监控中心 (Pro版)。

3.5 在Wordpress新建一个页面,页面中插入短代码:
总运行次数
总时长(小时)
成功率
| 状态 | 应用名称 | 开始时间 | 时长(秒) | 运行IP |
|---|---|---|---|---|
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-25 08:12:10 | 14826.6 | 180.157.4.196 |
| 成功 | 月报财报刷新 monthly_fresh |
2026-02-24 16:06:06 | 4023.34 | 180.157.4.196 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-24 07:42:39 | 6359.73 | 180.157.4.196 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-23 08:01:57 | 13031.2 | 180.157.4.196 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-22 08:20:49 | 14877.2 | 180.157.4.196 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-21 07:41:28 | 13300.7 | 180.157.4.12 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-20 09:23:32 | 11902 | 42.3.51.43 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-19 09:53:45 | 14778.5 | 180.157.4.12 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-18 09:01:17 | 13914.6 | 180.157.4.12 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-16 08:47:02 | 25676.5 | 180.157.4.12 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-15 07:50:08 | 8183.34 | 180.157.4.12 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-14 08:16:16 | 15200.6 | 180.157.4.12 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-13 11:27:39 | 14849.3 | 180.157.4.12 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-13 08:48:37 | 2285.46 | 180.157.4.12 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-12 09:08:58 | 14720.7 | 180.157.4.12 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-12 07:37:24 | 1835.17 | 180.157.4.12 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-11 08:00:30 | 15273.5 | 180.157.4.12 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-09 11:15:04 | 15109.5 | 180.157.4.12 |
| 成功 | 全数据下载分析 alldata_analysis |
2026-02-07 08:23:01 | 15311.8 | 180.157.4.12 |
| 成功 | 淘系数据下载分析 taodata_analyze |
2026-02-06 14:56:30 | 207.49 | 115.205.79.202 |

- 影刀准备工作
- 准备工作:安装 Requests 库 打开影刀 -> 环境管理 -> 自定义依赖 -> 添加 requests。
- 影刀流程内添加指令,记录运行开始时间:
在流程的最开始位置,添加影刀指令:日期时间转为时间戳,获取变量"start_ts"。
这个获取的时间戳,看起来是小数,但实际上是以文本格式传递,因此下面还要将这个变量转换为浮点数。

- 构建异常处理结构 (Try-Catch)
为了统计应用运行"失败"的情况,整个业务逻辑必须包裹在异常处理中。
- 添加一个 【异常处理 (Try-Catch)】 组件。
- 将你原有的所有业务流程节点,拖动到 Try 分支中。
- 结束节点:计算时长并上报到 WordPress
新建Python模块,输入以下代码:
import time
import requests
import datetime
def main(args):
# 1. 从参数获取变量
app_key = args.get("v_app_key", "unknown_app")
app_name = args.get("v_app_name", "未命名应用")
start_ts = args.get("v_start_time", 0)
status = args.get("status", "success") # 默认为成功
# 2. 计算时间和时长
end_ts = time.time()
if start_ts == 0:
duration = 0 # 防止未运行起始节点
else:
duration = round(end_ts - start_ts, 2)
# 转换为 SQL 格式 (YYYY-MM-DD HH:MM:SS)
# 注意:Windows下 timestamp 可能是 float
start_str = datetime.datetime.fromtimestamp(start_ts).strftime('%Y-%m-%d %H:%M:%S')
end_str = datetime.datetime.fromtimestamp(end_ts).strftime('%Y-%m-%d %H:%M:%S')
# 3. 配置接口信息 (请替换你的域名和密钥)
API_URL = "https://你的域名/wp-json/rpa-stat/v1/report"
SECRET_KEY = "your_secure_secret_123456"
# 4. 构造数据包 (注意:不包含IP,IP由服务器自动获取)
payload = {
"secret_key": SECRET_KEY,
"app_key": app_key,
"app_name": app_name, # 新增:应用中文名
"start_time": start_str,
"end_time": end_str,
"duration": duration,
"status": status
}
# 5. 发送请求
try:
# verify=False 用于跳过 SSL 证书验证(防止自签证书报错),正式环境建议设为 True
res = requests.post(API_URL, json=payload, timeout=5, verify=False)
if res.status_code == 200:
print(f"上报成功: [{app_name}] 耗时 {duration}秒")
else:
print(f"上报失败: {res.status_code} - {res.text}")
except Exception as e:
print(f"上报网络错误: {e}")
设置以下变量,作为这个Python模块的输入参数:

将这个Python模块插入主流程,设置输入参数值:

注意v_start_time就是前面指令定义的时间戳变量,
v_app_name为应用的名称,可以使用中文,以便在页面查看。
v_app_key为录入数据库的应用身份,使用英文。
status:这个模块如果是插入try__Catch___的Try语句中,就设置为文本"success",插入Catch语句,则设置为"failed",便于区分应用状态。
注意事项
- 接口安全:务必将SECRET_KEY替换为复杂的随机字符串(如 32 位字母 + 数字),防止他人恶意调用接口;
- 异常处理:影刀流程若中途报错终止,结束节点的代码可能无法执行。可在影刀中添加「异常捕获」节点,将上报代码放入异常处理逻辑,记录 "异常终止" 的时长(到报错时间为止);
- 网络权限:确保影刀所在环境能访问你的 WordPress 网站(若影刀在内网,需配置端口映射 / 公网访问);
- 数据备份:定期备份 WordPress 数据库(重点备份wp_rpa_run_stats表),避免数据丢失;
- 方法复用:如果有多个应用需要统计,可以把两段Python分别做成自定义指令,在需要统计的应用中直接调用。
最终效果
当你的影刀应用被他人运行时,每次运行都会自动向 WordPress 上报数据,你只需打开 WordPress 的统计页面(你的域名/rpa-report/),就能实时看到:
- 应用被运行的总次数;
- 累计运行的总时长(秒 / 小时);
- 运行者的IP地址;
- 运行的应用标识;
- 每一次运行的详细时间和时长(便于排查问题)。