Back to skills
extension
Category: Data & AnalyticsAPI key required

EZR 数据源导出(通用型)

从 EZR(驿氪) SCRM 后台导出数据源文件的通用能力。当用户需要获取 EZR 中的销售看板、分销导购、外呼、多人活码、短信、1V1群发,或任意业务数据(商品订单/会员/优惠券/退款等,见数据源目录)时触发。封装了 EZR 双模块认证(BigData RSA v头 / CRM AES _jmbody + SHA1 s头)、异步任务轮询定位(防串台)、按日/月累分裂、活码按添加日口径;提供可配置数据源清单(比音勒芬 8 源为内置示例,支持任意客户自定义 sources JSON);内置数据源目录与发现流程,可扩展覆盖 EZR 全平台数据;session 过期经 Chrome CDP 自动刷新(结构化 900 信号);多 AI/多进程并发下 cookie 原子写 + 写锁防竞态。

personAuthor: user_0d52066ahubcommunity

EZR 数据源导出(通用型)

30 秒上手(TL;DR)

  1. 装依赖:pip install pycryptodome requests
  2. 拿 session:浏览器 F12 → Application → Cookies → crm-tp.ezrpro.com 复制整串,存到本地文件,设 EZR_COOKIE_FILE=<该文件>不要硬编码进脚本
  3. 干跑看计划(不连网):python scripts/ezr_export.py --dry-run --date 2026-07-20
  4. 真实导出:python scripts/ezr_export.py --date 2026-07-20 --out ./out
  5. 定时免登录:用 ezr_auto_refresh.py 替代 ezr_export.py(需 Chrome 开 --remote-debugging-port=9222 且已登录 EZR),遇 900 自动刷新

想看原理 / 踩坑点 / 多 AI 并发安全,往下读「概述 / 核心难点 / 常见报错 FAQ」。

概述

提供从任意 EZR(驿氪)租户导出数据源文件的端到端能力:认证 → 触发导出 → 轮询任务 → 下载/解压。平台级逻辑(认证、轮询、下载)与具体业务无关;租户参数与数据源清单可配置。比音勒芬 8 源作为内置示例,真实客户只需提供一份 sources JSON 即可复用。

何时使用

  • 用户要"导出 EZR 数据 / 拉取驿氪报表 / 做比音勒芬数据日报的数据源"。
  • 需要把 EZR 后台的某类数据定期固化下来(可结合 when-to-create-skill 判断是否值得做成定时 skill)。
  • 跨客户复用:换 --brand-id / --user-id,或提供自定义 --sources 配置。

使用方法

  1. 安装依赖:pip install pycryptodome requests
  2. 获取 session(二选一,不要硬编码):
    • 完整 cookie:设环境变量 EZR_COOKIE_FILE=<cookie文件路径>(浏览器 F12 → Application → Cookies → crm-tp.ezrpro.com 复制整串存入文件)
    • 仅 pcl_sid:设 EZR_SESSION=<pcl_sid值>

🔒 凭据安全(务必遵守):cookie / pcl_sid 只存于本地文件(EZR_COOKIE_FILE)或环境变量,绝不写入代码、也绝不提交到仓库ezr_auto_refresh.py 经 CDP 读取的 cookie 也只落地到本地文件,并用原子写 + 写锁防止并发竞态与泄露。请勿把 cookie 粘进脚本或 commit。

  1. 干跑验证计划(不连网): python scripts/ezr_export.py --dry-run --start 2026-07-17 --end 2026-07-19
  2. 真实导出: python scripts/ezr_export.py --start 2026-07-17 --end 2026-07-19 --out <输出目录> python scripts/ezr_export.py --date 2026-07-20(按汇报日自动推算数据范围)
  3. 换租户 / 自定义: python scripts/ezr_export.py --user-id <uid> --brand-id <bid> --sources my_sources.json ...

⭐ session 自动刷新(定时任务免人工复制 Cookie)

scripts/ezr_auto_refresh.pyezr_export.py 的包装器:当 EZR 返回 ErrorMsg=900(session 过期)时,自动通过 Chrome CDP 从已登录的 Chrome 读取最新 pcl_sid(含 HttpOnly)写入 cookie 文件并重试,无需人工干预。配套 scripts/cdp_get_ezr_cookie.mjs(Node 22+)。

前置(一次性):Chrome 已登录 EZR,且开启远程调试(chrome://inspect/#remote-debugging 勾 Allow,或快捷方式加 --remote-debugging-port=9222)。

用法(参数同 ezr_export.py,附加 --force-refresh / --no-refresh / --cookie-file / --cdp-port):

python scripts/ezr_auto_refresh.py --date 2026-07-20 --out <输出目录>
  • 遇 900 → 自动 CDP 刷新 → 重试一次;重试仍失败则退出码非 0 并提示原因。
  • 会话过期判定(结构化信号)ezr_export.py 在捕获 EZRSessionExpired(ErrorMsg=900)时,会在输出中单独打印一行唯一标记 EZR_SESSION_EXPIRED;包装器 ezr_auto_refresh.py 仅匹配该标记即可精准命中,不再依赖脆弱的中文串组合匹配(旧逻辑 "900" in out and "session" in out.lower() 易被其它上下文误触发)。文案/语言改动不会影响自动刷新。

⭐ 通用性:数据源目录与发现流程(本 skill 是"通用"的关键)

本 skill 的导出机制与业务无关(认证/触发/轮询/下载全通用),但"EZR 里有哪些数据可拿"必须靠活目录 + 发现流程支撑,否则遇到新需求(如商品订单、会员、优惠券)只能靠猜 endpoint。

  • 数据源目录 references/data_source_catalog.md:地图。列出已确认源(内置 8 源)与典型待确认业务域(商品订单/会员/优惠券/退款/门店…),每域标注 UI 位置 + 模块猜测,作为"下次去哪找"的起点。
  • 发现流程 references/discovery.md:标准动作。用 web-access 登录 EZR → 在目标报表页抓导出按钮的 XHR(得 endpoint/body/模块,并从导出任务列表拿 Type)→ 用 scripts/ezr_discover.py 真实触发一次、确认产物结构 → 入库并回填目录。
  • 探针工具 scripts/ezr_discover.py:把"捕获到的 endpoint"变成"已验证的源"。真实触发小范围导出、下载并打印文件/zip 内层/xlsx sheet 名/首行表头,无需 openpyxl。

原则:宁可标"待确认"也不编造 endpoint。目录里 [待确认] 的行都须经 discovery 流程钉死 Type 与精确路径后才能改 [已知]。本机无可用 session 时无法当场枚举全部数据源,但发现流程让任何新需求都能被快速、可靠地定位。

  • 配套文档:免登录自动刷新/认证原理见 references/auth.md;数据源目录见 references/data_source_catalog.md;发现流程见 references/discovery.md

⭐ 多 AI / 多进程并发安全(共用同一 Chrome + 同一 EZR 后台时)

当设备上有多个 AI(或多个定时任务)共用同一个已登录的 Chrome、访问同一个 EZR 后台时,会涉及三类冲突面,本 skill 已做对应处理:

  • 浏览器 / CDP(9222):本 skill 不自行启动 Chrome,只连接已开着的、带 --remote-debugging-port=9222 的 Chrome。CDP 协议支持多客户端同时连同一 Chrome,故多 AI 连同一浏览器不会互相"占住"。冲突仅出现在"某 AI 自起 Chrome 抢 9222"的极端情况(本 skill 不做此动作)。
  • EZR 登录会话(同账号 pcl_sid):多 AI 共用同一份 pcl_sid = 同一账号复用同一 cookie,不会因"后登录踢前登录"而互相挤下线(这比各自登录更安全)。风险仅在并发导出任务可能串台/被限流;若改用不同 EZR 账号登录同一后台,EZR 若有单会话策略反而会真互踢——故推荐共享账号。
  • Cookie 文件(磁盘竞态,已根治):以前默认 ezr_cookie.txt 被所有调用共享,并发刷新会互相覆盖、读者读到半截 → 900。现:
    • 原子写write_cookie_file 先写 .tmpos.replace 原子替换(Windows MoveFileEx / POSIX rename)→ 读者(ezr_export.py)任何时刻都读到完整旧文件或完整新文件,绝无半截。
    • 写锁_cookie_write_lock<cookie_file>.lockO_EXCL 原子创建串行化并发刷新(跨平台,含 120s 过期锁清理防死锁;超时 30s 报错提示手动删锁)。锁按 cookie 文件路径派生,不同账号/不同路径互不阻塞。

多 AI 部署建议

  • 共享同一 EZR 账号(推荐,最省事):所有 AI 用同一个 EZR_COOKIE_FILE + 上述写锁;但不要同时跑大量导出,错峰即可。
  • 需要真正隔离:给每个 AI 配 独立的 EZR 子账号;或 独立的 Chrome 用户数据目录 + 各自 9222 端口(如 9223 / 9224,用 --cdp-port / EZR_CDP_PORT 区分),并各自指向独立的 EZR_COOKIE_FILE

核心难点(务必注意)

  • 轮询防串台(daily 源必须用 strict_day)GetDownList租户(品牌)级共享的,里面混着同名但数据范围不同的历史/他人任务。例:20260719分销导购数据导出 既有真单日(Querys StartTime=EndTime=2026-07-19,导购业绩=4239)也有三天范围(Querys StartTime=2026-07-17,=14620 三天之和)的 Status=2 任务。只按"日期字符串+CreateDate最新"会挑到跨天的错报告。poll_task 对 daily 型源强制 strict_day 校验:解析 Querys 起止日期,只接受起止都==当天 的真单日报告,跨天/累计一律排除。month_end 型(分销月累/活码月累/1V1)不应用 strict_day。单日活码额外用 exclude_keywords=["累计"]
  • GetDownList 时间窗(两个坑):① 不能按运行当天过滤(原 BegDate=EndDate=today 是 bug)——任务可能是更早日期建的(如 7/21 重导 7/19 数据时,那份单日任务是 7/20 建的),会被窗口挡掉导致轮询超时、文件保留旧错值。现改为最近 120 天窗 + match_name + strict_day + 最新 定位。② EZR 限制查询时间段不得超过 180 天,窗太宽会报"查询时间段超过了180天"而整体失败。120 天是安全上限内的值。
  • 认证/字段BigData 用 RSA v 头(明文 Body);CRM 用 AES _jmbody + SHA1 s 头。ErrorMsg=900 = session 过期需重登(由 EZRSessionExpired 异常 + EZR_SESSION_EXPIRED 标记结构化上报,供自动刷新包装器精准识别)。需数字类型的字段用 {brand_id!int} 渲染为整数。
  • 活码按添加日口径:多人活码按 LogCreateDateBeg/End(添加时间)筛选,不是报告范围;单日分别筛选 + 累计一份。
  • 依赖pip install pycryptodome requests(xlsx 直接下载,无需 openpyxl)。

常见报错 FAQ(用户向排查)

  • Q1:报 EZR_SESSION_EXPIRED / ErrorMsg=900(session 过期) → 含义:pcl_sid 失效,需重新登录。 → 处理:① 用 ezr_auto_refresh.py(推荐,自动经 CDP 从已登录 Chrome 刷新);② 或手动到 EZR 网页登录一次、重新复制 cookie 写入 EZR_COOKIE_FILE。 → 仍失败:确认 Chrome 里 EZR 确实处于「已登录」状态(不是停在登录页),且已开 --remote-debugging-port=9222

  • Q2:导出的数字对不上 / 混进了其它日期的数据(串台) → 含义:daily 源(分销按日等)从租户级共享任务列表挑报告时,挑到了跨天 / 累计的错报告。 → 处理:daily 型源本 skill 默认强制 strict_day 校验(只接受起止都 == 当天);用 --date 2026-07-20 按汇报日单日导出,不要人为放大 --start/--end 范围冒充单日。

  • Q3:报错「获取 cookie 写锁超时」/ <cookie_file>.lock 残留 → 含义:上一次刷新被强杀,残留锁文件未清理。 → 处理:删掉 <cookie_file>.lock 后重试(锁含 120s 过期自动清理,等一会通常也会自愈)。

  • Q4:报「查询时间段超过了180天」 → 含义:EZR 限制单次查询窗 ≤180 天。 → 处理:缩小 --start/--end 范围再跑;本 skill 内部轮询窗已设为 120 天安全上限。

  • Q5:CDP 取 cookie 失败 / 提示缺少 cdp helper → 处理:确认 Node 22+ 已装、scripts/cdp_get_ezr_cookie.mjs 存在;确认 Chrome 已开 9222 且已登录 EZR。

参考

  • references/auth.md — 双模块认证原理、v/s 头算法、session 安全
  • references/data_sources.md — 数据源格式差异、按日/月累、活码口径、8 源清单、自定义 sources JSON 写法
  • references/data_source_catalog.mdEZR 数据源目录(通用地图):已确认源 + 待确认业务域速查
  • references/discovery.md发现任意新数据源的标准流程 + ezr_discover.py 用法
  • scripts/ezr_discover.py — 新数据源探针:验证 endpoint/Type 并打印产物结构(无 openpyxl 依赖)