一人公司没有数据团队,但你仍然需要看板:推广链接每天带来多少点击、竞品价格有没有变动、关键词排名涨跌、VPS 延迟波动……这些数据散落在十几个后台,手动逐个打开抄一遍,一周就坚持不下去。
正确姿势是搭一条全自动数据流水线:采集 → 清洗 → 入库 → 可视化 → 定时调度。本篇把每一环的零成本选型和代码骨架讲透。
全链路选型(全部有免费档)
| 环节 | 轻量方案(本机/小数据) | 零成本上云方案 |
|---|---|---|
| 采集 | Python + httpx / requests | 同左,跑在 GitHub Actions |
| 动态页面 | Playwright(无头浏览器) | Playwright on Actions(加缓存) |
| 清洗 | pandas / 纯 Python | 同左 |
| 存储 | SQLite(一个文件) | Supabase Postgres 500MB 免费档 |
| 可视化 | Metabase 本地容器 | Grafana Cloud 免费档(1 万 series) |
| 调度 | 系统定时任务 / cron | GitHub 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://你的域名/; [email protected])"},
)
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(推荐,手机能看)
- 注册 Grafana Cloud 免费档,拿到托管 Prometheus/数据源地址;
- 采集器写入时多发一份到 Grafana 的 HTTP endpoint,或让 Grafana 直连 Supabase Postgres(Connections → PostgreSQL);
- 在 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 或放弃; - 不采集个人信息、不绕过登录与付费墙、不碰邮箱/手机号这类数据;
- 控制频率:单站点间隔至少数秒,失败时指数退避,绝不写死循环高频请求;
- 只存做决策必需的字段,数据留存设期限;商用前评估对方版权与数据使用条款。
你今天就能跑的最小闭环
- 选一个你真正关心的指标(比如某个推广后台的点击数、一个竞品价格);
- 写 30 行 httpx 脚本 + SQLite 落库;
- 加一个每天一次的 GitHub Actions 定时任务;
- 注册 Grafana Cloud 连库,建一个折线图 + 一条「停止更新」告警。
跑通这一条,剩下所有看板都是同一个模式的复制。下一篇讲怎么把内容发布也自动化:写完数据源,网站自动上线。