使用 OpenClaw 进行数据分析和可视化

第 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 提供了三个核心文件操作工具:readwriteedit。这些工具是进行本地数据处理的基础。

2.1.1 读取文件(read)

read 工具用于读取文件内容,支持文本文件和图片文件。

复制代码
# 使用 read 工具读取 CSV 文件
# 工具调用参数:
{
    "tool": "read",
    "path": "/home/admin/data/sales.csv"
}

对于大文件,read 支持 offsetlimit 参数进行分块读取:

复制代码
# 读取文件的前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 进行统计分析的方法:

  1. 环境配置 :通过 pip3 安装数据分析依赖
  2. 工具选择 :使用 exec 工具执行 Python 脚本
  3. 分析流程:数据读取 → 统计计算 → 结果输出
  4. 实战案例:完整的销售数据分析示例

通过结合 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 进行图表生成的方法:

  1. 环境配置 :使用 Agg 后端支持无 GUI 环境
  2. 图表类型:趋势图、柱状图、饼图等常见类型
  3. 保存格式:支持 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} |

## 二、销售图表

### 产品销售排名

![产品销售排名]({charts['product_ranking']})

## 三、数据明细

| 产品 | 销售额 | 销量 |
|------|--------|------|
"""
    
    # 添加数据明细(从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 小结

本章介绍了报告自动化的完整实现方案:

  1. 定时任务 :通过 openclaw cron 配置每日/周期性任务
  2. 实战案例:完整的日报自动化流程

通过 Cron 定时任务 + Python 数据分析 ,可以实现真正的数据驱动自动化,让销售日报、监控报告等定时自动生成并推送到相关群组。

「待验证」- cron 任务在生产环境中的稳定性


至此,《使用 OpenClaw 进行数据分析和可视化》系列文章已完成。第 4-6 章涵盖了统计分析、图表生成和报告自动化的完整技术方案。

第 7 章 最佳实践与注意事项

7.1 性能优化建议

数据处理优化

  • 使用 read 工具的 offsetlimit 参数分块读取大文件,避免一次性加载过多数据导致超时
  • 对于大量数据写入,优先使用 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=gatewayhost=node
  • 提权操作需要显式设置 elevated: true 并获得用户批准

网络访问限制

  • web_fetch 阻止私有/内部主机名访问,防止 SSRF 攻击
  • 重定向次数受 maxRedirects 限制(默认 3 次)
  • 响应体大小在解析前被限制,防止资源耗尽

7.3 常见问题解决

Python 包未安装

  • 问题:执行 Python 脚本时提示模块不存在
  • 解决:使用 pip3 install <package> 安装所需包
  • 注意:matplotlib 在无 GUI 环境下需设置 Agg 后端

中文字体显示问题(待验证)

  • 问题:图表中文显示为方框
  • 解决方案:指定系统中文字体路径,或使用英文标签

大文件读取超时

  • 问题:读取大文件时超时或输出被截断
  • 解决:使用 offsetlimit 参数分块读取

7.4 工具使用技巧

文件操作组合拳

  • 大文件编辑:先用 read + limit 预览,定位后用 edit 精确修改
  • 数据清洗:read 读取 → exec 执行 Python 处理 → write 保存结果

定时任务最佳实践

  • 使用 --session isolated 创建独立会话,避免污染主上下文
  • 一次性提醒使用 --at + --delete-after-run,自动清理
  • 周期性任务添加 --announce 参数,便于追踪执行状态

第 8 章 总结

8.1 全文回顾

本文系统介绍了使用 OpenClaw 进行数据分析和可视化的完整流程。从核心文件操作工具(readwriteedit)和命令执行工具(execprocess)开始,到网络数据抓取(web_fetchbrowser)、Python 数据处理、图表生成,再定时任务(cron),覆盖了数据分析全链路。

8.2 核心要点

  • 工具链完备:OpenClaw 提供从数据获取、处理、可视化到文档生成的完整工具链
  • 灵活执行模式:支持沙箱、网关、节点等多种执行环境,满足不同安全需求
  • 自动化能力:cron 定时任务支持一次性和周期性任务,实现数据分析自动化

8.3 后续学习建议

  1. 实践练习:从简单的 CSV 文件处理开始,逐步尝试网页数据抓取和图表生成
  2. 深入文档 :查阅 OpenClaw 官方文档 了解更多工具细节
  3. 社区交流:参与社区讨论,分享使用经验和最佳实践
  4. 场景拓展:探索更多应用场景,如日报生成、数据监控、自动化报告等

技术描述基于 OpenClaw 官方文档及工具验证,部分功能状态标注「待验证」需实际测试确认。

相关推荐
智慧化智能化数字化方案2 小时前
数字化转型——解读107页企业数字化转型整体规划-技术篇【附全文阅读】
大数据·人工智能·企业数字化转型整体规划
敏编程2 小时前
一天一个Python库:soupsieve - CSS 选择器在 Beautiful Soup 中的力量
开发语言·css·python
星爷AG I2 小时前
16-6 问题解决(AGI基础理论)
人工智能·agi
树獭非懒2 小时前
Google A2UI:让 AI 智能体「开口说界面」
前端·人工智能·后端
大大大大晴天2 小时前
Flink技术实践-超时异常踩坑与优化
大数据·flink·kafka
kronos.荒2 小时前
图论之腐烂橘子_BFS(python)
python·图论·bfs
AI职业加油站2 小时前
数字时代先机:大数据采集工程师
大数据·人工智能·机器学习·职场和发展
王哥儿聊AI2 小时前
微软开源神器MarkItDown:一键把PPT/PDF/Excel转成markdown,LLM直呼内行!
人工智能·深度学习·microsoft·机器学习·开源·powerpoint
love530love2 小时前
【独家资源】Windows 本地部署微软 BitNet b1.58: Flash Attention + CUDA GPU 加速 (sm_86) + AVX2 优化 + 1.58bit 量化
人工智能·windows·microsoft·llama.cpp·bitnet·flash attention·bitlinear_cpp