自动化 · 10 分钟阅读

自己做数据看板(上):自动采集、清洗入库与零成本可视化

用 Python(httpx/Playwright)定时采集网页与接口数据,清洗后写入 SQLite/Supabase,再用 Grafana Cloud 免费档或 Metabase 做出实时数据看板的完整链路。

一人公司没有数据团队,但你仍然需要看板:推广链接每天带来多少点击、竞品价格有没有变动、关键词排名涨跌、VPS 延迟波动……这些数据散落在十几个后台,手动逐个打开抄一遍,一周就坚持不下去。

正确姿势是搭一条全自动数据流水线:采集 → 清洗 → 入库 → 可视化 → 定时调度。本篇把每一环的零成本选型和代码骨架讲透。

全链路选型(全部有免费档)

环节轻量方案(本机/小数据)零成本上云方案
采集Python + httpx / requests同左,跑在 GitHub Actions
动态页面Playwright(无头浏览器)Playwright on Actions(加缓存)
清洗pandas / 纯 Python同左
存储SQLite(一个文件)Supabase Postgres 500MB 免费档
可视化Metabase 本地容器Grafana Cloud 免费档(1 万 series)
调度系统定时任务 / cronGitHub Actions cron
告警UptimeRobot 免费档Grafana Alerting → 邮件/Telegram

数据量小(每天几千行以内),SQLite + 本机 Metabase 最省心;要随时随地在手机上看图,再上 Supabase + Grafana Cloud。

第一步:写采集器——先试接口,再上浏览器

90% 的网页数据不需要无头浏览器。打开浏览器开发者工具 → Network → Fetch/XHR,刷新页面,找到返回 JSON 的那个请求,复制为 cURL,再转成 Python。优先顺序永远是:

公开 JSON 接口 > 官方 API > HTML 解析(httpx + selectolax/BeautifulSoup)> Playwright 渲染

最小采集器骨架:

# collector.py —— 采集 → 校验 → 去重 → 入库
import sqlite3
from datetime import datetime, timezone
import httpx

def fetch(url: str) -> dict:
    resp = httpx.get(
        url,
        timeout=15,
        headers={"User-Agent": "opc-dashboard/0.1 (+https://你的域名/; contact=you@example.com)"},
    )
    resp.raise_for_status()
    return resp.json()

def save(rows: list[dict]) -> int:
    con = sqlite3.connect("data/metrics.db")
    con.execute("""
        CREATE TABLE IF NOT EXISTS prices (
            id TEXT PRIMARY KEY,
            name TEXT,
            price REAL,
            checked_at TEXT NOT NULL
        )
    """)
    n = 0
    for r in rows:
        cur = con.execute(
            "INSERT OR IGNORE INTO prices (id, name, price, checked_at) VALUES (?,?,?,?)",
            (r["id"], r["name"], r["price"], datetime.now(timezone.utc).isoformat()),
        )
        n += cur.rowcount
    con.commit()
    con.close()
    return n  # 实际新增行数,天然去重

if __name__ == "__main__":
    data = fetch("https://example.com/api/products")
    print("新增", save(data), "行")

要点:

  • 写一个诚实的 User-Agent(标明用途和联系方式),这是低成本爬虫的基本礼貌;
  • 用主键 INSERT OR IGNORE 去重,重跑脚本也不会产生脏数据;
  • 每次入库都记 checked_at,看板的时间轴全靠它。

页面内容靠 JS 渲染、实在找不到接口时再请出 Playwright:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.goto("https://example.com/report", wait_until="networkidle")
    page.locator("table").wait_for()
    html = page.content()   # 拿到渲染后的 HTML 再解析
    page.screenshot(path="data/snapshot.png", full_page=True)
    browser.close()

Playwright 比 httpx 慢几十倍、也更容易触发风控,只在必要时用。

第二步:定时调度——不买服务器也能 7×24

直接复用模块一讲过的 GitHub Actions,加一个定时工作流 .github/workflows/collect.yml:

name: collect-metrics

on:
  schedule:
    - cron: '17 */6 * * *'   # 每 6 小时一次,避开整点高峰
  workflow_dispatch:          # 支持手动触发

jobs:
  collect:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
          cache: pip
      - run: pip install -r requirements.txt
      - run: python collector.py
      # 用 SQLite:把更新后的数据文件提交回仓库(低写入量场景可行)
      - uses: stefanzweifel/git-auto-commit-action@v5
        with:
          commit_message: 'chore: snapshot metrics'
          file_pattern: 'data/*.db'

数据稍大或要多人/多端看图,就把 save() 目标换成 Supabase:Python 用 supabase SDK 或直接 Postgres 连接串 upsert,Actions 里用 Secret 存连接串(参考免费数据库与 Actions 入门里的安全红线)。

第三步:搭看板——两种免费路径

路径 A:Grafana Cloud(推荐,手机能看)

  1. 注册 Grafana Cloud 免费档,拿到托管 Prometheus/数据源地址;
  2. 采集器写入时多发一份到 Grafana 的 HTTP endpoint,或让 Grafana 直连 Supabase Postgres(Connections → PostgreSQL);
  3. 在 Explore 里写一条 SQL,确认数据通,再点 Add to dashboard:
SELECT
  $__timeGroup(checked_at, '6h') AS time,
  name AS metric,
  AVG(price) AS value
FROM prices
WHERE $__timeFilter(checked_at)
GROUP BY 1, 2
ORDER BY 1;

折线图、Stat 卡片、表格三个面板就能覆盖 80% 的需求。

路径 B:Metabase 自托管(数据在自己手里)

一台 VPS 上一行 Docker 启动(VPS 选购见模块三):

docker run -d -p 3000:3000 \
  -v $PWD/metabase-data:/metabase.db \
  --name metabase metabase/metabase

浏览器打开 http://服务器IP:3000 完成初始化,添加 SQLite/Postgres 数据源,之后完全拖拽建图表,不用写前端。配合 Cloudflare Tunnel 或反代加 HTTPS 再开放访问,别把 3000 端口裸奔到公网。

第四步:让看板「主动找你」——告警

看板最大的敌人是没人看。给关键指标配告警:

  • Grafana Alerting:价格跌破阈值、数据 12 小时没更新(这条最重要,采集挂了第一时间知道);
  • 通知渠道免费选邮件或 Telegram Bot;
  • 没有告警系统时,在 Actions 脚本里判断异常后 raise,让工作流失败——GitHub 会自动发失败邮件,零成本兜底告警。

合规与风控红线(务必读完再写采集器)

  • 尊重 robots.txt 与服务条款,禁止采集的站点不要硬来,找官方 API 或放弃;
  • 不采集个人信息、不绕过登录与付费墙、不碰邮箱/手机号这类数据;
  • 控制频率:单站点间隔至少数秒,失败时指数退避,绝不写死循环高频请求;
  • 只存做决策必需的字段,数据留存设期限;商用前评估对方版权与数据使用条款。

你今天就能跑的最小闭环

  1. 选一个你真正关心的指标(比如某个推广后台的点击数、一个竞品价格);
  2. 写 30 行 httpx 脚本 + SQLite 落库;
  3. 加一个每天一次的 GitHub Actions 定时任务;
  4. 注册 Grafana Cloud 连库,建一个折线图 + 一条「停止更新」告警。

跑通这一条,剩下所有看板都是同一个模式的复制。下一篇讲怎么把内容发布也自动化:写完数据源,网站自动上线。