# 用 Python 把网站流量 API 变成可比较的 CSV

用 Python 和网站流量 API 导出竞品比较 CSV

下载完整 Python 脚本，用真实 API 实录离线复算或请求新数据，导出月份、访问量与置信度，并正确处理缺失月份、限流和认证错误。

Vaneform · 核对日期： 2026-10-09

一张有用的竞品 CSV，除了域名和流量，还需要写清数字对应哪个月，保留计算变化所需的历史，并让请求失败或无数据的行继续可见。本文提供完整的 Python 标准库脚本、三个站点的真实 API 字段实录，以及生成的 9 行 CSV。可以先离线复算文章，再接入自己的密钥读取新结果。

## 先离线复算，确认自己拿到了什么

将 Python 文件和 JSON 节选下载到同一文件夹，使用 Python 3.10 及以上运行，无需安装第三方包。实录读取于 2026 年 10 月 9 日（UTC+8），来自 umami.is、simpleanalytics.com 和 screenshotone.com 的 /api/v1/domains/{domain}/scale 成功请求。节选仅保留本教程使用的字段，数值保持原样，文件中没有请求凭证。

在该文件夹运行下方命令，会得到 9 行：每个域名分别对应 2026 年 6、7、8 月。第一条可用月份的 previous_visits 和 mom_change_pct 留空，因为这份实录没有 5 月数据。脚本会拒绝覆盖已有输出文件，下一次运行时换一个文件名，便于保留两次结果。也可以先下载现成 CSV，确认列结构是否适合自己的工作表。

~~~
python3 traffic-to-csv.py \
  --snapshot traffic-api-snapshot-2026-10-09.json \
  --output traffic-replay.csv

# Wrote 9 rows; 0 unavailable/error rows.
~~~

- [下载完整 Python 脚本](https://vaneform.com/downloads/traffic-to-csv.py) — Python 3.10 及以上，仅使用标准库，支持真实请求和离线复算。
- [下载 API 实录字段节选（JSON）](https://vaneform.com/downloads/traffic-api-snapshot-2026-10-09.json) — 从三次成功 API 响应中原样节选教程所需字段，包含三个站点，无凭证。
- [下载真实流量序列（CSV）](https://vaneform.com/downloads/traffic-comparison-2026-06-to-08.csv) — 9 条域名与月份记录，保留原始数值、日期、置信度和计算得到的环比。

## 响应里的月份和日期，分别怎样使用

Simple Analytics 响应中的 scale.month 为 2026-08，scale.as_of 为 2026-08-01，estimate 为 site，confidence 为 medium。monthly_visits 数组分别给出 6 至 8 月的 79,593、113,086、107,563 次访问。下方节选来自真实响应。月初的 as_of 是资源提供的日期，导出时保留作为来源信息；统计周期由 month 和每个序列点的月份确认。

实录还包含 retrieved_at，记录 HTTP 读取时的 UTC 时间戳。它可能比 UTC+8 的编辑日期早一个日历日。统计月份、资源 as_of 和读取时间这三个概念应分别保留。10 月请求得到 8 月记录符合该端点的 cache_only 行为：它读取已保存资源，成功请求本身不会推进数据月份。

CSV 将资源的 confidence 与 as_of 附在历史点旁，方便数据离开页面后继续追溯。响应没有为每个历史月单独提供置信度，因此这两列应按资源元数据阅读。需要回查原始结构时，保留 JSON。脚本只导出全站月访问序列；搜索估计和渠道比例属于其他分析任务，未被混入这组访问列。

接入更大的数据流程时，可将来源响应保存为核查记录，把 CSV 作为派生视图。成功响应中省略的字段，应在自己的模型中继续缺省或明确不可用。导出器要求可用全站序列带有来源信息和有效非负数，并拒绝重复月份，避免任意选择一条。接口契约发生变化时，先查看原载荷，再有依据地修改转换规则。

~~~
{
  "month": "2026-08",
  "as_of": "2026-08-01",
  "confidence": "medium",
  "estimate": "site",
  "visits": 107563,
  "monthly_visits": [
    { "month": "2026-06", "visits": 79593 },
    { "month": "2026-07", "visits": 113086 },
    { "month": "2026-08", "visits": 107563 }
  ]
}
~~~

参考资料:

- [Vaneform OpenAPI 契约](https://vaneform.com/api/v1/openapi.json)

## 接入密钥，读取当前保存的资源

打开 Vaneform 账号，使用自己的 API 密钥。普通域名读取使用 API 月度积分，取得新的可用域名结果时可能扣点。共享的 24 小时账号与域名回执，以及当前套餐限制，以 API 文档为准。这里仅请求 scale 资源，没有追加 Pro 搜索扩展，也没有启动批量采集任务。

在 macOS 或 Linux 的 bash、zsh 中，下面第一条命令会等待粘贴密钥，输入时不回显。按回车后导出变量，再运行脚本。密钥应留在环境变量中，避免写进 Python、CSV 或共享的终端记录。其他 shell 可用对应方式设置 VANEFORM_API_KEY，再使用相同 Python 参数。实时读取可能返回更新的月份或修订后的历史值，与保存实录产生差异时应保留两个版本。

~~~
read -r -s VANEFORM_API_KEY
export VANEFORM_API_KEY
python3 traffic-to-csv.py umami.is simpleanalytics.com \
  --month 2026-08 --output traffic-live-2026-08.csv
unset VANEFORM_API_KEY
~~~

参考资料:

- [API 访问、积分与错误说明](https://vaneform.com/docs/api)

## 选定一个月，保持比较对象一致

在离线命令中加上 --month 2026-08，即可得到三条 8 月记录。脚本会在 monthly_visits 中寻找精确月份，并查找紧邻的上一自然月；即使数组乱序也会正确处理。序列中间缺月时，不会把上一条可用观察自动当成 7 月。省略 --month 则按域名导出全部已记录月份，并在每个域名内部排序。

计算式为（本月 / 上月 − 1）× 100。Simple Analytics 的（107563 / 113086 − 1）× 100 四舍五入后为 −4.88%。因此 mom_change_pct 保存的是 −4.88，采用百分数值口径。导入表格后可以按普通数字显示，并在列名注明 %；需要应用表格百分比格式时，先除以 100。直接套百分比格式可能显示成 −488%，这是格式理解的问题。

真实记录为零时保留零；基数缺失或基数为零导致无法相除时，增长列留空。先筛选 row_status=ok 并确认共同月份，再按访问量排序。8 月这组三站的估计规模依次为 Umami、ScreenshotOne、Simple Analytics。这个顺序可以描述活动规模；要用于竞品优先级，还应先判断产品和用户任务是否可比。

| domain | month | visits | mom_change_pct |
| --- | --- | --- | --- |
| umami.is | 2026-08 | 481833 | 21.35 |
| simpleanalytics.com | 2026-08 | 107563 | -4.88 |
| screenshotone.com | 2026-08 | 120401 | 11.34 |

8 月离线复算的部分列；访问为估计值，资源置信度均为 medium。

## 接入自动任务前，亲自导出一次缺失月份

再次离线运行时使用 --month 2026-05，并更换输出文件名。实录没有 5 月点，预期得到三条 month_unavailable，访问列为空，退出码为 1。将它与 8 月结果并排打开：域名依然可见，日期和原因解释了为何不能纳入 5 月合计。这个小检查能让你理解失败行的意义，避免只凭行数齐全就相信整张表。

导入表格时，将 month 设为文本、visits 设为数值，并保留空单元格。批量执行“空值填零”会破坏脚本特意保留的状态差异。文件使用带 BOM 的 UTF-8，帮助常见表格应用识别编码。后续再次需要 JSON 时，使用保存的节选，避免从扁平 CSV 猜回原本没有输出的字段。

可重复执行的任务可以按读取日期保留文件夹，先比较覆盖情况，再比较增长。如果十个预期域名只剩八条可用记录，应先检查另外两条失败状态，再判断合计是否下降。任务配置中保留脚本版本，改动导出器后先运行离线示例，就能用已知结果核对行为，同时无需消耗 API 积分。

~~~
python3 traffic-to-csv.py \
  --snapshot traffic-api-snapshot-2026-10-09.json \
  --month 2026-05 --output traffic-missing-may.csv

# Wrote 3 rows; 3 unavailable/error rows.
# Exit status: 1
~~~

## 失败记录也是导出结果的一部分

序列没有所选月时，输出 month_unavailable，访问列留空；scale 资源缺失或报错时输出 scale_unavailable；搜索估计会得到 unsupported_estimate，因为当前文件用于全站访问。历史格式损坏或来源元数据缺失会输出 invalid_response。保留这些行，可以让比较名单中的失败对象继续可见，防止悄悄消失后改变统计分母。

认证错误、积分耗尽和其他失败 HTTP 响应输出 request_error，并保留 error_code。对于 500、502、503、504 和 lookup_rate_exceeded，脚本最多尝试三次，间隔有限。凭证与积分问题需要处理后重新运行；网络失败直接记录，避免无休止重试。脚本拒绝跳转，将 Bearer 密钥限定在固定的 Vaneform API 地址上。

退出码 0 表示所选记录都可用；1 表示 CSV 中包含不可用或错误行；2 表示输入、配置或输出问题让导出无法完成。用于定时任务时，应先检查退出码，再将文件送入看板。保存带日期的导出，检查覆盖变化，追加快照时保留原统计月份，这样后续研究才有可以回查的依据。

## 继续研究

- [打开 API 文档](https://vaneform.com/zh/docs/api)
- [阅读真实比较案例](https://vaneform.com/zh/guides/compare-website-traffic)
- [规划 API 接入](https://vaneform.com/zh/guides/website-traffic-api-guide)

Canonical: https://vaneform.com/zh/guides/website-traffic-api-python-csv
