Apify Storage 与导出:结果该放哪、怎么拿出来
披露:本页含联盟推广链接。你通过本页链接注册 Apify 并付费,我们可能获得佣金——不影响你支付的价格,也不改变我们如实记录的实测数据。 我们如何实测 →
证据口径:本页于 2026-07-31 按 Apify Storage、Dataset、Key-value store、Request queue 与 Get dataset items 官方文档核对。示例只展示安全调用结构,没有使用本站 token,也没有触发新的 run。
多数采集任务完成后,结果会进入默认 Dataset;但 Storage 不只有 Dataset。先按数据形态选存储,能避免把文件硬塞进表格,或把抓取队列误当成最终结果。
三种存储:用途与写入特性
| 存储 | 适合放什么 | 写入特性与边界 |
|---|---|---|
| Dataset | 一行一个对象的结构化结果,例如商家、商品、帖子 | 首次写入 item 时为 run 创建;顺序追加,已有 item 不能原地修改或删除 |
| Key-value store | JSON、HTML、图片、压缩包、文本等按 key 读取的内容 | 每个 run 会分配默认 store;记录可新增、覆盖或删除,并保留 MIME 类型 |
| Request queue | 待处理、处理中或需要重试的 URL/请求 | 用于抓取调度、去重与恢复,不是给业务人员直接交付的结果表 |
跨系统接入时不要猜存储 ID:从触发的 Run 对象读取 defaultDatasetId、defaultKeyValueStoreId 或 defaultRequestQueueId。如果 Actor 没有向 Dataset 写入 item,不能因为 run 成功就假设已有非空结果表。
路径 A:在 Console 里导出
- 打开本次 Run 的 Output / Dataset。
- 先在 Table 或 JSON 视图抽查字段、空值与重复项。
- 点 Export,按下游选择 CSV、XLSX、JSON 或 JSONL 等格式。
- 把输入条件、Run ID、Dataset ID 和导出时间一起记录,避免文件脱离来源。
选择建议:
- 交给运营或直接进表格:CSV / XLSX。
- 保留嵌套对象和数组:JSON / JSONL。
- 数据量大、要流式处理:优先 JSONL,不要先装进一个巨大的表格文件。
路径 B:用 API 读取 Dataset
先把 token 放在运行环境的秘密变量里,不要写进代码、聊天、URL 或日志。官方推荐 Authorization header:
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?format=json&limit=100" \
-H "Authorization: Bearer $APIFY_TOKEN"
导出 CSV 并只保留需要的列:
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?format=csv&fields=name%2Curl%2Cprice&outputFields=title%2Clink%2Camount&clean=1" \
-H "Authorization: Bearer $APIFY_TOKEN" \
--output results.csv
fields 用来选择和排序字段,逗号按官方示例编码为 %2C。outputFields 按位置重命名这些字段,必须同时提供 fields,并且名称数量一致。omit 可排除字段;同一字段同时出现在 fields 与 omit 时,omit 优先。
clean、flatten、unwind 怎么选
| 参数 | 作用 | 容易误判的地方 |
|---|---|---|
clean=1 | 跳过空 item,并移除以 # 开头的隐藏字段 | 返回条数可能少于 limit,不能只按本页数组长度判断结束 |
flatten=metadata | 把嵌套对象转成 metadata.source 一类扁平键 | 原嵌套对象会被扁平结构替换,先用小样本核对列名 |
unwind=images | 把数组元素逐个与父对象合并成记录 | 一个原始 item 可能展开为多行,导出行数不再等于 Dataset item 数 |
需要保留原始嵌套结构时优先 JSON/JSONL;要进表格时再决定是否 flatten 或 unwind。这些参数会改变字段或行数,不只是显示样式。
分页要看响应头,不要猜
Dataset items API 未设置 limit 时没有默认条数上限。大结果为了控制内存和失败重试范围,建议显式设置 limit 与 offset,并读取四个响应头:
X-Apify-Pagination-Offset:当前批次起始位置。X-Apify-Pagination-Limit:当前批次最多读取的原始 item 数。X-Apify-Pagination-Count:当前响应实际返回的记录数。X-Apify-Pagination-Total:Dataset 的原始 item 总数。
分页以原始 item 为粒度,即使使用 unwind 也不改变这个规则。使用 clean=1 后 Count 可能小于 Limit,所以不要用“本页不足 100 条”作为唯一停止条件;应按 Offset、Limit 与 Total 覆盖完整范围。
导出前的五项检查
| 问题 | 为什么重要 |
|---|---|
| Dataset 是否属于正确 Run | “最后一次运行”可能不是你正在验收的那次 |
| 关键字段是否稳定 | Actor 更新后字段可能更名、变类型或变空 |
| 是否显式限制批次 | 设置了 limit 就必须按分页响应头推进 offset |
| 是否保留来源和采集时间 | 没有 provenance 的数据难以复核和更新 |
| 存储是否需要命名 | 具名存储长期保留;未命名存储受当前 plan、保留期和最近 run 规则影响 |
常见失败条件
- CSV 打开后列错位:嵌套对象或数组不适合直接展平;改用 JSON/JSONL,或先在下游明确展开规则。
- API 返回空数组:先核对 Dataset ID、Run 状态、访问权限与 offset,不要立即重跑制造重复费用。
- 自动化拿错一批数据:始终从触发的 Run 读取
defaultDatasetId,不要把一次测试的 Dataset ID 永久写死。 - 导出条数突然变多或变少:检查是否启用了
clean或unwind,再对照 Dataset 原始 item 总数。 - 长期任务找不到旧结果:为需要长期保留的存储命名,并定期验证 Storage 总览中的当前保留策略;不要依赖写死的统一天数。
要把“导出一次”变成稳定管道,下一步是先保存 Task,再用 Schedule 或 n8n 在 run 完成后处理对应 Dataset;认证、状态门禁与 Run ID 处理见 Apify API 指南。
先从一份真实 Dataset 看懂字段,再决定 CSV、JSON 还是 API。
apify/google-search-scraper 按 $0.0045/条计,$5 免费额度约合 1,111 条;不绑卡,跑完再决定要不要付费。
免费跑我自己的第一批 →