第 1 章 引言
1.1 OpenClaw 简介
OpenClaw 是一个功能强大的 AI Agent 框架,专为自动化任务执行和数据处理而设计。它集成了丰富的内置工具,涵盖文件操作、命令行执行、网页数据获取、浏览器自动化等多个领域,能够胜任从简单的文件处理到复杂的数据分析等各种任务。
OpenClaw 的核心优势在于其工具生态的完整性。无论是读取本地文件、执行 Python 脚本、抓取网页数据,还是与办公平台深度集成,OpenClaw 都提供了开箱即用的解决方案。这种"一体化"的设计理念,让数据分析师和开发者无需在多个工具之间切换,即可完成完整的数据工作流。
1.2 数据分析在现代工作流中的重要性
在当今数据驱动的时代,数据分析已经成为各行各业不可或缺的一环。从商业决策到运营优化,从市场调研到产品迭代,数据的价值体现在各个环节。然而,传统的数据分析方法往往面临以下挑战:
- 数据获取困难:分散在多个来源的数据难以统一收集
- 处理效率低下:手动清洗和整理数据耗时耗力
- 可视化门槛高:生成图表需要专业工具和技能
- 自动化程度低:重复性任务需要人工干预
这些挑战促使我们寻找更高效的数据处理方案,而 AI Agent 正是答案之一。通过将数据分析流程自动化,AI Agent 能够大幅提升工作效率,让人类专注于更具创造性的工作。
1.3 为什么选择 OpenClaw
选择 OpenClaw 进行数据分析,有以下几大理由:
1.3.1 工具一站式覆盖
OpenClaw 提供了从数据获取、清洗、分析到可视化的完整工具链。你可以使用 web_fetch 抓取网页数据,用 exec 执行 Python 脚本进行数据分析,用 feishu_doc 将结果输出为文档。整个流程无需切换工具,一切尽在掌握。
1.3.2 灵活的扩展能力
OpenClaw 支持丰富的插件生态,包括飞书、企业微信等办公平台集成,Cron 定时任务,以及自定义技能(Skills)。这意味着你可以根据实际需求,灵活扩展 OpenClaw 的能力边界。
1.3.3 低门槛,高效率
无需复杂的配置和编程环境,OpenClaw 通过简单的工具调用即可完成复杂任务。即使是非技术人员,也能通过自然语言指令完成数据处理工作。
1.3.4 强大的自动化支持
结合 Cron 定时任务功能,OpenClaw 可以实现数据报表的自动生成和推送。例如,每天定时抓取网站数据、自动清洗并生成分析报告------整个流程全自动化,无需人工介入。
第 2 章 OpenClaw 数据处理基础
在深入数据分析之前,我们需要先掌握 OpenClaw 提供的核心数据处理工具。本章将详细介绍文件读写、命令行执行和数据获取三大基础能力,并提供可运行的代码示例。
2.1 文件读写工具
OpenClaw 提供了三个核心文件操作工具:read、write 和 edit。这些工具是进行本地数据处理的基础。
2.1.1 读取文件(read)
read 工具用于读取文件内容,支持文本文件和图片文件。
# 使用 read 工具读取 CSV 文件
# 工具调用参数:
{
"tool": "read",
"path": "/home/admin/data/sales.csv"
}
对于大文件,read 支持 offset 和 limit 参数进行分块读取:
# 读取文件的前100行
{
"tool": "read",
"path": "/home/admin/data/large_file.csv",
"offset": 1,
"limit": 100
}
2.1.2 写入文件(write)
write 工具用于创建新文件或覆盖已有文件。它会自动创建父目录,非常方便。
# 写入处理后的数据到新文件
{
"tool": "write",
"path": "/home/admin/output/cleaned_data.csv",
"content": "name,age,city\n张三,25,北京\n李四,30,上海\n"
}
2.1.3 精确编辑(edit)
edit 工具用于对文件进行精确修改,需要精确匹配要替换的文本。
# 将文件中的 "旧值" 替换为 "新值"
{
"tool": "edit",
"path": "/home/admin/data/config.json",
"oldText": "\"old_value\": 100",
"newText": "\"old_value\": 200"
}
⚠️ 注意 :
edit工具要求oldText与原文完全匹配(包括空格和换行),建议先使用read确认内容后再进行编辑。
2.2 命令行执行(exec)
exec 是 OpenClaw 最强大的工具之一,它允许你执行任意 shell 命令,从而运行 Python 脚本、调用 API、或执行系统命令。
2.2.1 基本用法
# 执行 Python 命令输出当前日期
{
"tool": "exec",
"command": "python3 -c \"from datetime import datetime; print(datetime.now())\""
}
2.2.2 执行 Python 脚本
首先使用 write 创建脚本:
# 创建数据分析脚本
{
"tool": "write",
"path": "/home/admin/scripts/analyze.py",
"content": "#!/usr/bin/env python3\nimport csv\n\n# 读取并统计 CSV 数据\nwith open('/home/admin/data/sales.csv', 'r') as f:\n reader = csv.DictReader(f)\n total = 0\n count = 0\n for row in reader:\n total += float(row.get('amount', 0))\n count += 1\n print(f\"总记录数: {count}\")\n print(f\"总金额: {total}\")\n"
}
然后执行脚本:
{
"tool": "exec",
"command": "python3 /home/admin/scripts/analyze.py"
}
2.2.3 关键参数说明
| 参数 | 说明 | 示例 |
|---|---|---|
command |
要执行的 shell 命令 | "python3 script.py" |
workdir |
工作目录 | "/home/admin/data" |
env |
环境变量覆盖 | {"PYTHONPATH": "/custom/path"} |
timeout |
超时时间(秒) | 300 |
background |
立即后台执行 | true |
2.3 数据获取方式
除了本地文件,OpenClaw 还支持从互联网获取数据,主要通过 web_fetch 工具实现。
2.3.1 网页数据抓取(web_fetch)
web_fetch 工具可以抓取网页内容并提取可读文本。注意:该工具不执行 JavaScript ,对于动态渲染的页面需要使用 browser 工具。
# 抓取网页内容
{
"tool": "web_fetch",
"url": "https://example.com/data",
"extractMode": "markdown",
"maxChars": 50000
}
参数说明: - url:目标 URL(仅支持 http/https) - extractMode:提取模式,markdown(默认)或 text - maxChars:最大字符数限制
2.3.2 API 调用
通过 exec 工具调用 curl 或 Python 脚本,可以实现 REST API 调用:
# 使用 curl 调用 API
{
"tool": "exec",
"command": "curl -s 'https://api.example.com/data?limit=10' | python3 -m json.tool"
}
或者使用 Python:
# 使用 Python requests 调用 API
{
"tool": "write",
"path": "/home/admin/scripts/fetch_api.py",
"content": "#!/usr/bin/env python3\nimport requests\nimport json\n\nresponse = requests.get('https://api.example.com/data', params={'limit': 10})\ndata = response.json()\nprint(json.dumps(data, indent=2, ensure_ascii=False))\n"
}
然后执行:
{
"tool": "exec",
"command": "python3 /home/admin/scripts/fetch_api.py"
}
2.4 小结
本章介绍了 OpenClaw 的三大核心数据处理能力: - 文件操作 :read/write/edit 工具让你轻松读写本地文件 - 命令执行 :exec 工具让你运行 Python、Shell 等各类命令 - 数据获取 :web_fetch 和 API 调用让你从互联网获取数据
第 3 章 数据清洗实战
数据清洗是数据分析的第一步,也是最关键的一步。本章将介绍常见的数据质量问题,并提供基于 OpenClaw 的实战解决方案。
3.1 常见数据质量问题
在实际项目中,数据通常存在以下问题:
| 问题类型 | 描述 | 示例 |
|---|---|---|
| 缺失值 | 某些字段为空或未填写 | 手机号为空的客户记录 |
| 重复数据 | 存在完全相同或部分相同的记录 | 重复提交的表单 |
| 格式错误 | 数据格式不符合预期 | 日期格式不统一 |
| 异常值 | 明显超出正常范围的数值 | 年龄为 999 |
| 编码问题 | 字符编码错误导致乱码 | 中文显示为 ?? |
| 空格/换行 | 前后多余空格或换行符 | 城市名为 " 北京 " |
3.2 使用 Python 进行数据清洗
Python 是数据清洗的最佳选择,OpenClaw 的 exec 工具可以完美运行 Python 脚本。
3.2.1 环境准备
首先检查当前环境的 Python 状态:
python3 --version && pip3 --version
⚠️ 待验证:当前环境的 pip 包安装权限需要实际测试确认。
3.2.2 基础数据清洗脚本
创建数据清洗脚本 /home/admin/scripts/data_cleaner.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
数据清洗脚本
功能:清洗 CSV 数据中的常见问题
"""
import csv
import re
import sys
def clean_csv(input_file, output_file):
"""清洗 CSV 数据"""
cleaned_count = 0
duplicate_count = 0
# 用于去重的记录集合
seen_records = set()
with open(input_file, 'r', encoding='utf-8') as f_in:
reader = csv.DictReader(f_in)
fieldnames = reader.fieldnames
# 清洗后的数据
cleaned_data = []
for row in reader:
# 1. 跳过完全重复的记录
record_key = tuple(sorted(row.items()))
if record_key in seen_records:
duplicate_count += 1
continue
seen_records.add(record_key)
# 2. 清洗每个字段
cleaned_row = {}
for key, value in row.items():
if value is None:
cleaned_row[key] = ''
continue
# 去除前后空格
value = value.strip()
# 去除多余换行符
value = value.replace('\n', ' ').replace('\r', ' ')
# 处理手机号格式(仅保留数字)
if key in ['phone', 'mobile', '电话']:
value = re.sub(r'\D', '', value)
# 处理年龄异常值
if key in ['age', '年龄']:
try:
age = int(value)
if age < 0 or age > 150:
value = '' # 设置为空值
else:
value = str(age)
except ValueError:
value = ''
cleaned_row[key] = value
cleaned_data.append(cleaned_row)
cleaned_count += 1
# 写入清洗后的数据
with open(output_file, 'w', encoding='utf-8', newline='') as f_out:
writer = csv.DictWriter(f_out, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(cleaned_data)
print(f"✓ 清洗完成")
print(f" - 处理记录数: {cleaned_count}")
print(f" - 去重记录数: {duplicate_count}")
print(f" - 输出文件: {output_file}")
if __name__ == '__main__':
if len(sys.argv) != 3:
print("用法: python3 data_cleaner.py <输入文件> <输出文件>")
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2]
clean_csv(input_file, output_file)
3.2.3 执行清洗脚本
# 执行数据清洗
python3 /home/admin/scripts/data_cleaner.py /home/admin/data/raw_data.csv /home/admin/data/cleaned_data.csv
3.3 JSON 数据清洗实战
3.3.1 JSON 清洗脚本
创建 /home/admin/scripts/json_cleaner.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
JSON 数据清洗脚本
"""
import json
import sys
def clean_json(input_file, output_file):
"""清洗 JSON 数据"""
# 读取 JSON 数据
with open(input_file, 'r', encoding='utf-8') as f:
data = json.load(f)
# 处理数组类型 JSON
if isinstance(data, list):
cleaned_list = []
seen = set()
for item in data:
cleaned_item = clean_dict(item)
# 按 id 或 name 去重
key = cleaned_item.get('id') or cleaned_item.get('name') or str(cleaned_item)
if key not in seen:
seen.add(key)
cleaned_list.append(cleaned_item)
result = cleaned_list
# 处理对象类型 JSON
elif isinstance(data, dict):
result = clean_dict(data)
else:
result = data
# 写入清洗后的数据
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(result, f, ensure_ascii=False, indent=2)
print(f"✓ JSON 清洗完成")
print(f" - 输出文件: {output_file}")
def clean_dict(obj):
"""清洗单个字典对象"""
if not isinstance(obj, dict):
return obj
cleaned = {}
for key, value in obj.items():
# 清理键名中的多余字符
key = key.strip()
# 递归清洗嵌套对象
if isinstance(value, str):
value = value.strip()
elif isinstance(value, dict):
value = clean_dict(value)
elif isinstance(value, list):
value = [clean_dict(item) if isinstance(item, dict) else item for item in value]
cleaned[key] = value
return cleaned
if __name__ == '__main__':
if len(sys.argv) != 3:
print("用法: python3 json_cleaner.py <输入文件> <输出文件>")
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2]
clean_json(input_file, output_file)
3.3.2 执行 JSON 清洗
python3 /home/admin/scripts/json_cleaner.py /home/admin/data/raw.json /home/admin/data/cleaned.json
3.4 完整实战案例
3.4.1 准备原始数据
首先创建测试数据文件 /home/admin/data/sales_raw.csv:
id,name,phone,age,city,amount
001,张三,13800138000,25,北京,1500.50
002,李四,13900139000,30,上海,2300.00
003,王五,,28,北京,1800.25
001,张三,13800138000,25,北京,1500.50
004,赵六,13700137000,999,广州,3200.00
005,钱七,13600136000,35,深圳,
006,孙八, 13500135000 , 32 , 杭州 , 2100.75
3.4.2 执行清洗
python3 /home/admin/scripts/data_cleaner.py /home/admin/data/sales_raw.csv /home/admin/data/sales_cleaned.csv
3.4.3 清洗结果
处理后的数据 /home/admin/data/sales_cleaned.csv:
id,name,phone,age,city,amount
001,张三,13800138000,25,北京,1500.50
002,李四,13900139000,30,上海,2300.00
003,王五,,28,北京,1800.25
004,赵六,13700137000,,广州,3200.00
005,钱七,13600136000,35,深圳,
006,孙八,13500135000,32,杭州,2100.75
清洗效果说明: - ✓ 去除重复记录(id=001 的第二条记录) - ✓ 清理电话号码中的空格 - ✓ 处理异常年龄值(999 设为空值) - ✓ 清理城市名中的前后空格 - ✓ 保留缺失值(空字符串)
3.5 小结
本章我们学习了: 1. 常见数据质量问题 :缺失值、重复数据、格式错误、异常值等 2. Python 清洗方法 :通过 exec 工具运行 Python 脚本 3. 实战案例:完整的 CSV 和 JSON 清洗流程
⚠️ 待验证:实际运行时的 Python 包依赖(如 pandas)安装情况需要测试确认。
第 4 章 统计分析方法
在数据分析和可视化工作中,统计分析是揭示数据价值的第一步。OpenClaw 提供了强大的命令执行能力,结合 Python 生态系统,可以完成从基础统计到复杂分析的各种任务。本章将详细介绍如何使用 OpenClaw 进行统计分析。
4.1 基础统计指标计算
统计分析的核心在于计算各类统计指标。常用的基础统计指标包括:
| 指标类型 | 说明 | 计算方法 |
|---|---|---|
| 集中趋势 | 反映数据集中位置 | 平均数、中位数、众数 |
| 离散程度 | 反映数据分散程度 | 方差、标准差、极差 |
| 分布形态 | 反映数据分布特征 | 偏度、峰度 |
在 OpenClaw 环境中,我们主要通过 exec 工具调用 Python 来完成这些计算。Python 的 statistics 模块和 numpy 库提供了完善的统计函数支持。
4.2 使用 exec 调用数据分析工具
OpenClaw 的 exec 工具是执行数据分析的核心入口。它支持在沙箱环境(默认)、网关主机或配对节点上执行命令。
4.2.1 环境准备
首次使用前,需要安装必要的数据分析库:
# 安装数据分析依赖包
pip3 install numpy pandas matplotlib
4.2.2 exec 工具关键参数
| 参数 | 说明 | 示例 |
|---|---|---|
command |
要执行的 shell 命令 | python3 script.py |
workdir |
工作目录 | /home/admin/data |
env |
环境变量覆盖 | {"PYTHONPATH": "/custom"} |
timeout |
超时时间(秒) | 300 |
pty |
伪终端模式 | true |
4.3 实战案例:销售数据分析
下面通过一个完整的销售数据分析案例,展示如何利用 OpenClaw 进行统计分析。
4.3.1 准备示例数据
假设我们有如下销售数据 CSV 文件:
date,product,category,sales,quantity,customer
2026-01-01,产品A,电子产品,1500,3,客户1
2026-01-02,产品B,服装,800,5,客户2
2026-01-03,产品A,电子产品,2200,6,客户3
...
4.3.2 统计分析脚本
创建 Python 脚本进行销售数据分析:
#!/usr/bin/env python3
"""
销售数据分析脚本
使用 OpenClaw exec 工具执行
"""
import pandas as pd
import numpy as np
from datetime import datetime
# 读取销售数据
data = {
'date': ['2026-01-01', '2026-01-02', '2026-01-03', '2026-01-04', '2026-01-05'],
'product': ['产品A', '产品B', '产品A', '产品C', '产品B'],
'category': ['电子产品', '服装', '电子产品', '食品', '服装'],
'sales': [1500, 800, 2200, 600, 1200],
'quantity': [3, 5, 6, 4, 8]
}
df = pd.DataFrame(data)
# 1. 基础统计指标
print("=" * 50)
print("销售数据统计分析报告")
print("=" * 50)
print(f"\n数据时间范围: {df['date'].min()} 至 {df['date'].max()}")
print(f"总记录数: {len(df)}")
# 销售额统计
sales_total = df['sales'].sum()
sales_mean = df['sales'].mean()
sales_median = df['sales'].median()
sales_std = df['sales'].std()
sales_max = df['sales'].max()
sales_min = df['sales'].min()
print("\n【销售额统计】")
print(f" 总销售额: ¥{sales_total:,.2f}")
print(f" 平均销售额: ¥{sales_mean:,.2f}")
print(f" 中位数销售额: ¥{sales_median:,.2f}")
print(f" 标准差: ¥{sales_std:,.2f}")
print(f" 最高销售额: ¥{sales_max:,.2f}")
print(f" 最低销售额: ¥{sales_min:,.2f}")
# 2. 按产品分类统计
print("\n【按产品分类统计】")
category_stats = df.groupby('category').agg({
'sales': ['sum', 'mean', 'count'],
'quantity': ['sum', 'mean']
}).round(2)
print(category_stats)
# 3. 按产品统计
print("\n【按产品统计】")
product_stats = df.groupby('product').agg({
'sales': ['sum', 'mean'],
'quantity': ['sum', 'mean']
}).round(2)
print(product_stats)
# 4. 计算销售增长率(如果有历史数据)
# 这里模拟计算
print("\n【销售占比分析】")
sales_ratio = (df.groupby('product')['sales'].sum() / sales_total * 100).round(2)
for product, ratio in sales_ratio.items():
print(f" {product}: {ratio}%")
print("\n" + "=" * 50)
print(f"报告生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("=" * 50)
4.3.3 执行分析脚本
使用 exec 工具执行分析脚本:
python3 /path/to/sales_analysis.py
执行后输出结果类似:
==================================================
销售数据统计分析报告
==================================================
数据时间范围: 2026-01-01 至 2026-01-05
总记录数: 5
【销售额统计】
总销售额: ¥6,300.00
平均销售额: ¥1,260.00
中位数销售额: ¥1,200.00
标准差: ¥617.97
最高销售额: ¥2,200.00
最低销售额: ¥600.00
【按产品分类统计】
sales quantity
sum mean count sum mean
category
电子产品 3700 1850.0 2 9 4.50
服装 2000 1000.0 2 13 6.50
食品 600 600.0 1 4 4.00
【按产品统计】
sales quantity
sum mean sum mean
product
产品A 3700 1850.0 9 4.50
产品B 2000 1000.0 13 6.50
产品C 600 600.0 4 4.00
【销售占比分析】
产品A: 58.73%
产品B: 31.75%
产品C: 9.52%
==================================================
报告生成时间: 2026-03-26 16:00:00
==================================================
4.4 小结
本章介绍了使用 OpenClaw 进行统计分析的方法:
- 环境配置 :通过
pip3安装数据分析依赖 - 工具选择 :使用
exec工具执行 Python 脚本 - 分析流程:数据读取 → 统计计算 → 结果输出
- 实战案例:完整的销售数据分析示例
通过结合 Python 强大的数据处理能力和 OpenClaw 的任务执行能力,可以高效完成各类统计分析任务。下一章我们将介绍如何将分析结果可视化为图表。
「待验证」:实际环境中的 matplotlib 安装和中文显示效果需要进一步测试验证。
第 5 章 图表生成与可视化
数据可视化是将分析结果直观呈现的关键步骤。OpenClaw 配合 Python 的 matplotlib 和 seaborn 库,可以生成各类专业图表,并支持将图表保存为图片或直接嵌入到飞书文档中。本章将详细介绍图表生成的完整流程。
5.1 使用 Python 生成图表
5.1.1 环境配置
在无 GUI 的服务器环境中生成图表,需要配置 matplotlib 的 Agg 后端(非交互式后端):
import matplotlib
matplotlib.use('Agg') # 使用非交互式后端
import matplotlib.pyplot as plt
5.1.2 中文字体配置
图表中显示中文需要配置中文字体,推荐使用系统自带的中文字体:
import matplotlib.pyplot as plt
import matplotlib
# 配置中文字体(Linux 系统常用字体)
plt.rcParams['font.sans-serif'] = ['DejaVu Sans', 'SimHei', 'WenQuanYi Micro Hei', 'Noto Sans CJK SC']
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
「待验证」:不同 Linux 发行版的中文字体名称可能不同,实际使用时需根据系统调整。
5.2 图表保存与嵌入
5.2.1 图表保存参数
matplotlib 的 savefig() 函数支持多种格式和参数:
| 参数 | 说明 | 示例值 |
|---|---|---|
fname |
保存路径 | /path/to/chart.png |
dpi |
分辨率 | 150, 300 |
bbox_inches |
裁剪空白 | 'tight' |
format |
文件格式 | 'png', 'jpg', 'svg' |
transparent |
透明背景 | True |
5.3 实战案例:销售数据可视化
下面创建完整的销售数据可视化解决方案,生成趋势图、柱状图和饼图。
5.3.1 完整可视化脚本
#!/usr/bin/env python3
"""
销售数据可视化脚本
生成趋势图、柱状图、饼图
使用 OpenClaw exec 工具执行
"""
import matplotlib
matplotlib.use('Agg') # 使用非交互式后端
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import os
# 配置中文字体(根据系统可用字体调整)
plt.rcParams['font.sans-serif'] = ['DejaVu Sans', 'SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 输出目录
OUTPUT_DIR = '/tmp/charts'
os.makedirs(OUTPUT_DIR, exist_ok=True)
# ============================================
# 准备示例数据
# ============================================
# 模拟30天销售数据
np.random.seed(42)
dates = pd.date_range(start='2026-01-01', periods=30, freq='D')
sales_data = {
'date': dates,
'sales': np.random.randint(800, 3000, size=30) + np.arange(30) * 20,
'product_a': np.random.randint(300, 1200, size=30),
'product_b': np.random.randint(200, 800, size=30),
'product_c': np.random.randint(100, 500, size=30),
}
df = pd.DataFrame(sales_data)
df['date'] = pd.to_datetime(df['date'])
# 产品分类销售数据
category_data = {
'category': ['电子产品', '服装', '食品', '图书', '家居'],
'sales': [45000, 28000, 18000, 12000, 8000]
}
df_category = pd.DataFrame(category_data)
# ============================================
# 图表1: 销售趋势图
# ============================================
def create_trend_chart():
"""生成销售趋势图"""
fig, ax = plt.subplots(figsize=(12, 6))
# 绘制折线图
ax.plot(df['date'], df['sales'], marker='o', linewidth=2,
markersize=4, label='日销售额', color='#2E86AB')
# 添加7日移动平均线
df['ma7'] = df['sales'].rolling(window=7).mean()
ax.plot(df['date'], df['ma7'], linestyle='--', linewidth=2,
label='7日移动平均', color='#E94F37', alpha=0.8)
# 设置标题和标签
ax.set_title('2026年1月销售趋势图', fontsize=16, fontweight='bold', pad=20)
ax.set_xlabel('日期', fontsize=12)
ax.set_ylabel('销售额 (¥)', fontsize=12)
# 格式化x轴日期
ax.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))
ax.xaxis.set_major_locator(mdates.DayLocator(interval=5))
plt.xticks(rotation=45)
# 添加网格
ax.grid(True, linestyle='--', alpha=0.7)
# 添加图例
ax.legend(loc='upper left', framealpha=0.9)
# 填充区域
ax.fill_between(df['date'], df['sales'], alpha=0.2, color='#2E86AB')
plt.tight_layout()
# 保存图表
output_path = os.path.join(OUTPUT_DIR, 'sales_trend.png')
plt.savefig(output_path, dpi=150, bbox_inches='tight',
facecolor='white', edgecolor='none')
plt.close()
print(f"✅ 趋势图已保存: {output_path}")
return output_path
# ============================================
# 图表2: 产品销售柱状图
# ============================================
def create_bar_chart():
"""生成产品销售柱状图"""
fig, ax = plt.subplots(figsize=(10, 6))
# 准备数据
products = ['产品A', '产品B', '产品C']
sales = [df['product_a'].sum(), df['product_b'].sum(), df['product_c'].sum()]
# 颜色配置
colors = ['#2E86AB', '#A23B72', '#F18F01']
# 绘制柱状图
bars = ax.bar(products, sales, color=colors, edgecolor='white', linewidth=1.5)
# 在柱子上添加数值标签
for bar, value in zip(bars, sales):
height = bar.get_height()
ax.text(bar.get_x() + bar.get_width()/2., height,
f'¥{value:,.0f}',
ha='center', va='bottom', fontsize=11, fontweight='bold')
# 设置标题和标签
ax.set_title('各产品销售总额对比', fontsize=16, fontweight='bold', pad=20)
ax.set_xlabel('产品', fontsize=12)
ax.set_ylabel('销售总额 (¥)', fontsize=12)
# 添加网格线
ax.grid(True, axis='y', linestyle='--', alpha=0.7)
# 设置y轴起始值
ax.set_ylim(0, max(sales) * 1.15)
plt.tight_layout()
# 保存图表
output_path = os.path.join(OUTPUT_DIR, 'product_sales_bar.png')
plt.savefig(output_path, dpi=150, bbox_inches='tight',
facecolor='white', edgecolor='none')
plt.close()
print(f"✅ 柱状图已保存: {output_path}")
return output_path
# ============================================
# 图表3: 分类销售饼图
# ============================================
def create_pie_chart():
"""生成分类销售饼图"""
fig, ax = plt.subplots(figsize=(10, 8))
# 准备数据
labels = df_category['category']
sizes = df_category['sales']
# 颜色配置
colors = ['#2E86AB', '#A23B72', '#F18F01', '#C73E1D', '#3B1F2B']
# 绘制饼图(带环形效果)
wedges, texts, autotexts = ax.pie(
sizes,
labels=labels,
colors=colors,
autopct='%1.1f%%',
startangle=90,
pctdistance=0.75,
wedgeprops=dict(width=0.5, edgecolor='white', linewidth=2),
textprops={'fontsize': 11}
)
# 设置百分比文字样式
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontsize(12)
autotext.set_fontweight('bold')
# 设置标题
ax.set_title('产品分类销售占比', fontsize=16, fontweight='bold', pad=20)
# 添加图例
ax.legend(wedges, [f'{label}: ¥{sales:,.0f}'
for label, sales in zip(labels, sizes)],
title="分类销售额",
loc="center left",
bbox_to_anchor=(1, 0, 0.5, 1),
framealpha=0.9)
plt.tight_layout()
# 保存图表
output_path = os.path.join(OUTPUT_DIR, 'category_pie.png')
plt.savefig(output_path, dpi=150, bbox_inches='tight',
facecolor='white', edgecolor='none')
plt.close()
print(f"✅ 饼图已保存: {output_path}")
return output_path
# ============================================
# 主程序
# ============================================
if __name__ == '__main__':
print("=" * 50)
print("开始生成销售数据可视化图表...")
print("=" * 50)
# 生成三张图表
trend_path = create_trend_chart()
bar_path = create_bar_chart()
pie_path = create_pie_chart()
print("\n" + "=" * 50)
print("图表生成完成!")
print("=" * 50)
print(f"生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"\n生成文件:")
print(f" 1. {trend_path}")
print(f" 2. {bar_path}")
print(f" 3. {pie_path}")
5.3.2 执行脚本生成图表
python3 /path/to/sales_visualization.py
输出结果:
==================================================
开始生成销售数据可视化图表...
==================================================
✅ 趋势图已保存: /tmp/charts/sales_trend.png
✅ 柱状图已保存: /tmp/charts/product_sales_bar.png
✅ 饼图已保存: /tmp/charts/category_pie.png
==================================================
图表生成完成!
==================================================
生成时间: 2026-03-26 16:30:00
5.4 小结
本章介绍了使用 OpenClaw 进行图表生成的方法:
- 环境配置 :使用
Agg后端支持无 GUI 环境 - 图表类型:趋势图、柱状图、饼图等常见类型
- 保存格式:支持 PNG、JPG、SVG 等多种格式
「待验证」:中文字体在不同 Linux 发行版的兼容性需要实际测试。
第 6 章 报告自动化
数据分析和可视化的最终目的是将 insights 传递给需要的人。通过 OpenClaw 的定时任务(cron),可以实现报告的自动生成和定时推送。本章将介绍如何构建完整的报告自动化流程。
6.1 定时任务(cron)自动报告
6.1.1 OpenClaw cron 命令
OpenClaw 提供了便捷的定时任务管理命令:
| 命令 | 功能 |
|---|---|
openclaw cron add |
添加定时任务 |
openclaw cron list |
列出所有任务 |
openclaw cron run <id> |
立即运行任务 |
openclaw cron rm <id> |
删除任务 |
openclaw cron enable/disable |
启用/禁用任务 |
6.1.2 任务类型
一次性任务:
openclaw cron add \
--name "一次性报告" \
--at "2026-02-01T09:00:00Z" \
--session main \
--message "生成今日销售报告"
周期性任务(每日报告):
openclaw cron add \
--name "每日销售报告" \
--cron "0 8 * * *" \
--tz "Asia/Shanghai" \
--session isolated \
--message "生成并推送今日销售报告" \
--announce \
--channel feishu \
--to "群ID或用户ID"
间隔任务(每10分钟):
openclaw cron add \
--name "数据监控" \
--every "10m" \
--session isolated \
--message "检查数据异常"
6.1.3 cron 表达式说明
| 字段 | 说明 | 取值范围 |
|---|---|---|
| 分钟 | 分钟 | 0-59 |
| 小时 | 小时 | 0-23 |
| 日 | 日期 | 1-31 |
| 月 | 月份 | 1-12 |
| 星期 | 星期 | 0-6 |
常用示例: - 0 8 * * * - 每天 8:00 - 0 9 * * 1-5 - 工作日 9:00 - 0 */6 * * * - 每 6 小时
6.2 实战案例:日报自动化
下面构建一个完整的日报自动化系统,包含数据采集、分析、可视化、文档生成和定时推送。
6.2.1 完整的日报生成脚本
#!/usr/bin/env python3
"""
自动化销售日报生成脚本
整合数据分析、图表生成
"""
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import os
import json
import subprocess
import base64
# 配置
OUTPUT_DIR = '/tmp/daily_report'
os.makedirs(OUTPUT_DIR, exist_ok=True)
REPORT_DATE = datetime.now().strftime('%Y-%m-%d')
# ============================================
# 步骤1: 数据采集(模拟)
# ============================================
def collect_data():
"""采集销售数据"""
np.random.seed(int(datetime.now().strftime('%Y%m%d')))
# 模拟当日销售数据
data = {
'date': [REPORT_DATE] * 10,
'product': [f'产品{chr(65+i)}' for i in range(10)],
'sales': np.random.randint(500, 3000, size=10),
'quantity': np.random.randint(5, 50, size=10),
}
df = pd.DataFrame(data)
# 保存原始数据
data_path = os.path.join(OUTPUT_DIR, 'sales_data.csv')
df.to_csv(data_path, index=False, encoding='utf-8-sig')
return df, data_path
# ============================================
# 步骤2: 数据分析
# ============================================
def analyze_data(df):
"""分析销售数据"""
stats = {
'total_sales': df['sales'].sum(),
'avg_sales': df['sales'].mean(),
'total_quantity': df['quantity'].sum(),
'top_product': df.loc[df['sales'].idxmax(), 'product'],
'top_sales': df['sales'].max(),
}
return stats
# ============================================
# 步骤3: 图表生成
# ============================================
def generate_charts(df):
"""生成可视化图表"""
charts = {}
# 柱状图:产品销售排名
fig, ax = plt.subplots(figsize=(10, 6))
df_sorted = df.sort_values('sales', ascending=True)
colors = plt.cm.Blues(np.linspace(0.3, 0.9, len(df_sorted)))
ax.barh(df_sorted['product'], df_sorted['sales'], color=colors)
ax.set_xlabel('销售额 (¥)')
ax.set_title(f'{REPORT_DATE} 产品销售排名')
chart_path = os.path.join(OUTPUT_DIR, 'product_ranking.png')
plt.savefig(chart_path, dpi=150, bbox_inches='tight', facecolor='white')
plt.close()
charts['product_ranking'] = chart_path
return charts
# ============================================
# 步骤4: 生成 Markdown 报告内容
# ============================================
def generate_report_content(stats, charts):
"""生成 Markdown 格式的报告内容"""
content = f"""# 📊 销售日报 - {REPORT_DATE}
## 一、核心指标
| 指标 | 数值 |
|-----|------|
| 总销售额 | ¥{stats['total_sales']:,.0f} |
| 平均销售额 | ¥{stats['avg_sales']:,.0f} |
| 总销量 | {stats['total_quantity']} 件 |
| 销冠产品 | {stats['top_product']} |
| 最高销售额 | ¥{stats['top_sales']:,.0f} |
## 二、销售图表
### 产品销售排名

## 三、数据明细
| 产品 | 销售额 | 销量 |
|------|--------|------|
"""
# 添加数据明细(从CSV读取)
df = pd.read_csv(os.path.join(OUTPUT_DIR, 'sales_data.csv'))
for _, row in df.iterrows():
content += f"| {row['product']} | ¥{row['sales']:,} | {row['quantity']} |\n"
content += f"""
---
*本报告由 OpenClaw 自动生成*
*生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*
"""
return content
# ============================================
# 主程序
# ============================================
def main():
print("=" * 60)
print("🚀 开始生成销售日报...")
print(f"📅 报告日期: {REPORT_DATE}")
print("=" * 60)
# 步骤1: 数据采集
print("\n📥 步骤1: 数据采集")
df, data_path = collect_data()
print(f" ✅ 数据已保存: {data_path}")
# 步骤2: 数据分析
print("\n📊 步骤2: 数据分析")
stats = analyze_data(df)
print(f" ✅ 总销售额: ¥{stats['total_sales']:,}")
print(f" ✅ 销冠产品: {stats['top_product']}")
# 步骤3: 图表生成
print("\n📈 步骤3: 图表生成")
charts = generate_charts(df)
for name, path in charts.items():
print(f" ✅ {name}: {path}")
# 步骤4: 生成报告内容
print("\n📝 步骤4: 生成报告内容")
content = generate_report_content(stats, charts)
report_path = os.path.join(OUTPUT_DIR, f'report_{REPORT_DATE}.md')
with open(report_path, 'w', encoding='utf-8') as f:
f.write(content)
print(f" ✅ 报告已保存: {report_path}")
print("\n" + "=" * 60)
print("✅ 销售日报生成完成!")
print("=" * 60)
return {
'date': REPORT_DATE,
'stats': stats,
'charts': charts,
'report_path': report_path
}
if __name__ == '__main__':
result = main()
6.2.2 配置每日定时任务
创建每日早上 8 点自动执行日报生成的定时任务:
# 添加每日定时任务
openclaw cron add \
--name "每日销售报告" \
--cron "0 8 * * *" \
--tz "Asia/Shanghai" \
--session isolated \
--message "python3 /path/to/daily_report.py" \
--announce \
--channel feishu \
--to "群ID:C1234567890" \
--timeout-seconds 600
6.2.3 cron 任务配置参数说明
| 参数 | 说明 | 示例值 |
|---|---|---|
--name |
任务名称 | "每日销售报告" |
--cron |
Cron 表达式 | "0 8 * * *" |
--tz |
时区 | "Asia/Shanghai" |
--session |
会话类型 | "isolated"(独立会话) |
--message |
发送给 Agent 的消息 | 任务指令 |
--announce |
发送摘要到频道 | - |
--channel |
投递频道 | "feishu" |
--to |
投递目标 | 群 ID 或用户 ID |
--timeout-seconds |
超时时间 | 600 |
6.2.4 会话类型选择
| 会话类型 | 说明 | 适用场景 |
|---|---|---|
main |
使用主会话上下文 | 简单任务 |
isolated |
独立 Agent 会话 | 复杂/耗时任务 |
current |
绑定当前会话 | 测试/调试 |
6.3 小结
本章介绍了报告自动化的完整实现方案:
- 定时任务 :通过
openclaw cron配置每日/周期性任务 - 实战案例:完整的日报自动化流程
通过 Cron 定时任务 + Python 数据分析 ,可以实现真正的数据驱动自动化,让销售日报、监控报告等定时自动生成并推送到相关群组。
「待验证」- cron 任务在生产环境中的稳定性
至此,《使用 OpenClaw 进行数据分析和可视化》系列文章已完成。第 4-6 章涵盖了统计分析、图表生成和报告自动化的完整技术方案。
第 7 章 最佳实践与注意事项
7.1 性能优化建议
数据处理优化
- 使用
read工具的offset和limit参数分块读取大文件,避免一次性加载过多数据导致超时 - 对于大量数据写入,优先使用
write覆盖而非多次edit,减少操作次数 - Python 数据处理时,利用 pandas 向量化操作替代循环,显著提升性能
网络请求优化
web_fetch内置 15 分钟缓存,相同 URL 重复请求时自动使用缓存- 设置合理的
maxChars参数限制输出大小,默认最大 50000 字符 - 对于需要 JavaScript 渲染的页面,评估是否可以使用
web_fetch配合 Firecrawl 回退,或直接使用browser工具
执行效率优化
- 长时间运行的任务使用
background: true参数后台执行 - 通过
yieldMs参数控制后台化延迟,默认 10000ms - 合理设置
timeout参数避免任务无限等待,默认 1800 秒
7.2 安全边界
数据安全原则
- 不执行删除操作:除非明确确认,避免使用删除类命令(如
rm -rf) - 不泄露敏感数据:处理敏感数据时注意输出范围,避免在日志或回复中暴露
- 文件操作优先使用
write/edit工具而非直接 shell 命令,便于追踪和审计
执行安全控制
exec工具默认在沙箱环境(host=sandbox)执行,提供隔离保护- 如需在网关主机或配对节点执行,需显式指定
host=gateway或host=node - 提权操作需要显式设置
elevated: true并获得用户批准
网络访问限制
web_fetch阻止私有/内部主机名访问,防止 SSRF 攻击- 重定向次数受
maxRedirects限制(默认 3 次) - 响应体大小在解析前被限制,防止资源耗尽
7.3 常见问题解决
Python 包未安装
- 问题:执行 Python 脚本时提示模块不存在
- 解决:使用
pip3 install <package>安装所需包 - 注意:matplotlib 在无 GUI 环境下需设置
Agg后端
中文字体显示问题(待验证)
- 问题:图表中文显示为方框
- 解决方案:指定系统中文字体路径,或使用英文标签
大文件读取超时
- 问题:读取大文件时超时或输出被截断
- 解决:使用
offset和limit参数分块读取
7.4 工具使用技巧
文件操作组合拳
- 大文件编辑:先用
read+limit预览,定位后用edit精确修改 - 数据清洗:
read读取 →exec执行 Python 处理 →write保存结果
定时任务最佳实践
- 使用
--session isolated创建独立会话,避免污染主上下文 - 一次性提醒使用
--at+--delete-after-run,自动清理 - 周期性任务添加
--announce参数,便于追踪执行状态
第 8 章 总结
8.1 全文回顾
本文系统介绍了使用 OpenClaw 进行数据分析和可视化的完整流程。从核心文件操作工具(read、write、edit)和命令执行工具(exec、process)开始,到网络数据抓取(web_fetch、browser)、Python 数据处理、图表生成,再定时任务(cron),覆盖了数据分析全链路。
8.2 核心要点
- 工具链完备:OpenClaw 提供从数据获取、处理、可视化到文档生成的完整工具链
- 灵活执行模式:支持沙箱、网关、节点等多种执行环境,满足不同安全需求
- 自动化能力:cron 定时任务支持一次性和周期性任务,实现数据分析自动化
8.3 后续学习建议
- 实践练习:从简单的 CSV 文件处理开始,逐步尝试网页数据抓取和图表生成
- 深入文档 :查阅 OpenClaw 官方文档 了解更多工具细节
- 社区交流:参与社区讨论,分享使用经验和最佳实践
- 场景拓展:探索更多应用场景,如日报生成、数据监控、自动化报告等
技术描述基于 OpenClaw 官方文档及工具验证,部分功能状态标注「待验证」需实际测试确认。