k-skill 实战:用 ev-subsidy-status 无头查询韩国地区电动汽车购车补贴余量

k-skill 实战:用 ev-subsidy-status 无头查询韩国地区电动汽车购车补贴余量 k-skill 实战用 ev-subsidy-status 无头查询韩国地区电动汽车购车补贴余量【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill韩国环境部환경부无公害车综合网站무공해차 통합누리집会公开各地区电动汽车购车补贴的申请、交付与剩余数量但页面正文受pnp4web/penc脚本保护且接口通常依赖人工操作。k-skill 项目中的ev-subsidy-status技能封装了同名 npm 包源码位于 packages/ev-subsidy-status在不登录、不开浏览器、不配置 API Key 的情况下直接解析官方公开响应并恢复受保护的 HTML从而查询特定地区、特定车种电动乘用车/货车/客车的补贴余量、公告状态与模型级换算金额。读完本文你将掌握该技能的完整命令用法、pnp4web无代码执行的解码原理、公告状态判定优先级与全部失败模式可直接用于本地查询或作为 Agent 技能接入。技能定位与适用场景ev-subsidy-status 在仓库中既是一个 k-skillev-subsidy-status/skill.json也是一个可独立安装的 npm CLI 包。其定位非常明确只读查询韩国地方自治团体发布的电动汽车购车补贴民간공고(民间公告)、접수(受理)、출고(交付)、출고잔여(交付剩余)数量与公告状态不涉及申请、支付或任何写操作。技能元数据见 ev-subsidy-status/SKILL.md将该技能归类为local-info面向ko-KR用户典型问题是我家所在地区的电动乘用车补贴还剩多少、还能不能申请、某车型能拿多少补贴。在 Dolshoi 等运行时中它还会基于官方页面继续完成后续动作在通用环境中则只负责查询与汇总。核心卖点基本查询无需浏览器、API 密钥、登录或代理。只有在官方页面结构变更需要诊断、或需要精确读取模型级补贴时才可选择接入用户自行启动的 Aside Browser、BrowserOS 或 Chrome/Chromium CDP 会话。由于该公开页面本身是无密钥keyless公开接口因此不经过k-skill-proxy代理转发减少了链路复杂度。前置条件与公共访问路径运行环境要求Node.js 18package.json 中engines.node明确声明18因为代码使用全局fetch与URLSearchParamsev-subsidy-statusnpm 包仓库内版本为 0.2.0通过npx ev-subsidy-status ...直接调用。官方公开端点技能操作的两个官方页面基础全国支付现状页POST 提交查询参数https://ev.or.kr/nportal/buySupprt/initSubsidyPaymentCheckAction.do模型别补贴弹窗页POST 提交查询参数POST /nportal/buySupprt/psPopupLocalCarModelPrice.do yearyearlocal_cdregion-codecar_type11|12|13这两个端点在源码 constants.js 中分别定义为STATUS_URL与MODEL_SUBSIDY_PATH。car_type的取值范围11|12|13与三种车种一一对应11电动乘用车승용12电动货车화물13电动客车승합。已确认的 DOM 结构技能在开发时确认了官方页面的关键 DOM 选择器市道시도下拉#localDo_cd市郡区시군구下拉#local_cd1结果表格列시도市道、지역구분地区区分、차종구분车种区分、공고파일公告文件、접수방법受理方式、민간공고대수民间公告数量、접수대수受理数量、출고대수交付数量、출고잔여대수交付剩余数量、비고备注这些选择器是技能解析表格、识别包含출고잔여列的目标表格的依据见 http.js 中的extractStatusRows遍历所有table找到文本包含출고잔여的那张表。核心原理pnp4web 保护页面的无代码执行解码页面虽然无需登录即可访问但正文被pnp4web/penc混淆脚本保护——直接抓取得到的只是空壳shell HTML真正的支付现状表格被打包进了一个受保护的 payload需要通过官方下发的pnp4web.js字符表才能还原。ev-subsidy-status 的默认传输路径direct-http在 pnp.js 中实现了完整的解码流程其安全底线是绝不执行远程 JavaScript不使用eval/vm只做字符替换级解析。具体步骤如下识别空壳响应通过正则/meta[^]name[]penc[]/i判断页面是否带penc元标记只有带该标记才需要解码无标记则直接返回 HTML。提取pnp4web.jsURL用正则匹配script namepnp4web src...将相对路径基于STATUS_URL解析为绝对地址。下载官方字符表源码抓取pnp4web.js文本带缓存cachedPnp避免重复请求当 URL 变化或传入自定义 fetch 时重新获取。解析字符表先抽取var In[...]数组中的字符串分片逐一做\xHH/\uHHHH十六进制与 Unicode 转义还原再按o0:...到o6:...七个表达式从分片索引中拼出 7 组基础字母表任一字母表长度不足 64 即判定UPSTREAM_DECODE_FAILED。还原受保护 payload从空壳页面的onload_0xac(...)中提取加密串其首字符为字母表索引、次字符为轮换量rotation用轮换后的字母表按 Base64 变体规则逐 4 字符解出 3 字节最终Buffer.toString(utf8)得到真实 HTML。从源码结构看这种实现把脚本保护降维成静态字符表解析既绕过了对浏览器渲染的依赖也避免了在 Node 进程里执行第三方混淆代码的安全风险。官方脚本或 payload 格式一旦变化技能会以UPSTREAM_DECODE_FAILED找不到字符表、空 payload、非法标识符等明确报错而不是静默返回错误数据。解码完成后HTTP 路径还做了一件事检查解码后 HTML 中option selected的年份是否与请求年份一致不一致则抛YEAR_NOT_AVAILABLEhttp.js 的fetchDecodedStatusHtml从源头杜绝请求 2026 却拿到 2025 数据的错位。CLI 安装与命令总览包通过bin字段暴露ev-subsidy-status命令入口 cli.js支持status查询支付现状与regions搜索地区候选两个子命令。完整参数如下参数别名说明--region 지역-r市道 市郡区如경기 성남시status 命令必填--query 검색어-qregions 命令的地区搜索词--vehicle type—车种passenger/승용、cargo/화물、bus/승합默认passenger--year year—基准年份默认 Asia/Seoul 当前年--model model—查询模型别补贴与剩余换算值--transport t—direct-http默认或browser--provider p—browser 传输时的auto/aside/browseros/chrome-cdp--cdp-url url—用户已启动的 Chrome/BrowserOS CDP 地址--timeout ms—页面等待超时毫秒--json—输出 JSON默认输出人类可读文本命令行解析在parseArgs中实现同时支持--vehicle/--vehicle-type两种写法非 JSON 输出由formatStatus生成其中数量格式化函数formatCount会区分우선(优先)/법인·기관(法人·机构)/택시(出租车)/중소기업(中小企业)/일반(一般)明细。工作流一地区与车种归一化技能的第一步是规范化查询参数对应原指令 Workflow 第 1 步地区尽量以시도 시군구形式输入如경기 성남시。重名歧义像중구首尔、大田、釜山、仁川都有、강서구这类同名市郡区先用regions命令列出候选再让用户指定市道npx ev-subsidy-status regions --query 중구车种默认passenger전기승용支持passenger/승용、cargo/화물、bus/승합三种。年份默认取 Asia/Seoul 时区的当前年份。地区与车种归一化在源码中有完整映射constants.jsVEHICLE_TYPES定义了三种车种及其carTypeCode11/12/13与别名表resolveVehicleType对别名做小写归一后匹配无法识别时抛出VEHICLE_TYPE_NOT_AVAILABLESIDO_ALIASES收录了 17 个市道的全部写法如서울/서울시/서울특별시、강원/강원도/강원특별자치도canonicalSidoFromQuery用它把用户输入收敛为标准市道名localMatches支持去掉시/군/구后缀的模糊匹配如성남可命中성남시但必须short.length 2防止过度匹配。地区解析最终落到resolveRegionFromRowshttp.js在全表行中按市道 市郡区双重过滤去重后若为 0 行抛REGION_NOT_FOUND多于 1 个抛REGION_AMBIGUOUS并在details.candidates中给出全部候选方便用户二次选择恰好 1 个才确定地区代码。local_code从公告下载函数goDownloadFile(...)的第二个参数中读取市道代码则由其前两位拼00得出。工作流二查询官方支付现状确定地区后执行 status 查询npx ev-subsidy-status status \ --region 경기 성남시 \ --vehicle passenger \ --year 2026 \ --json该命令内部getSubsidyStatusHttp会向initSubsidyPaymentCheckAction.doPOST 提交car_type、year1、localDo_cdall、local_cd1all请求全国行再在客户端过滤目标地区。正常结果中transport应为direct-http说明走的是无需浏览器的默认路径。关键返回字段字段含义status.notice_count民间公告数量status.application_count受理申请数量status.delivered_count交付数量status.delivery_remaining_count交付剩余数量availability.label公告状态判定open/scheduled/closed/unknown 等status.note地方自治团体备注原文source.fetched_atKST 时区查询时间数值单元格以전체(总计) / 우선순위(优先) / 법인·기관(法人·机构) / 예약 대상군(预约对象群) / 일반(一般)五档保留乘用车的预约对象群是taxi出租车货车的对应别名为small_business中小企业CLI 文本输出中会按车种动态插入相应明细标签。值得注意的鲁棒性处理如果目标群体대상군数值为负数、或整体与部分之和不等技能不会擅自将值修正为 0而是保留原始数字并附加警告返回把异常如实暴露给上层原指令 Failure modes 结尾明确这一点。工作流三备注优先于数字的公告状态判定官方页面只给数量不给明确的还能不能申请结论因此技能实现了备注文本优先的状态判定availability.js 的classifyAvailability判定优先级如下备注含마감(截止)/소진(售罄)/접수 종료(受理结束)/신청 종료(申请结束)→closed备注含접수 예정(受理预定)/추경 예정(追加预算预定)/추가 공고 예정(追加公告预定)/재공고 예정(重新公告预定)→scheduled备注含접수 중(受理中)/신청 기간(申请期间)/접수 기간(受理期间)/신청 가능(可申请)→open无上述明示语、但剩余数量为正数 →unknown_with_remaining_count无任何判定依据 →unknownclassifyAvailability同时输出basis判定依据如note:closed、remaining_count:positive与warnings。一个关键规则是即便剩余数量为正只要备注明确写了截止/售罄就不得声称可申请——此时会生成警告 출고잔여대수는 양수지만 지자체 비고에는 마감 또는 소진으로 표시됩니다.剩余数量虽为正数但备注标注截止或售罄并仍以closed为准。工作流四模型指定时的补贴与换算官方页面只提供数量不提供金额。当用户关心具体车型能拿多少钱时可通过--model触发模型级查询npx ev-subsidy-status status \ --region 서울 강남구 \ --vehicle passenger \ --model 모델명 \ --json即使走直接 HTTP 路径技能也会用同一个年份、地区代码与车种调用psPopupLocalCarModelPrice.do解析模型表http.js 的extractModelSubsidySnapshot会筛选表头同时包含제조사(制造商)、모델(型号)、국비(国费)的表格并取行数最多的候选逐行解析制造商、模型、国费、地方费与合计。匹配处理有三条分支parseModelSubsidyRowsattachModelEstimate匹配到多个细分车型不擅自任选其一而是在model_subsidy_candidates中返回全部候选及各自的 1 台补贴与剩余换算值并追加警告提示按配置trim区分确认恰好匹配一个细分车型额外返回model_subsidy与remaining_budget.model_equivalent_estimate_krw匹配不到保留地区级数量结果设置model_lookup_error并输出警告模型查询失败不影响地区数量结果。换算值的含义与边界remaining_budget.model_equivalent_estimate_krw的计算假设是官方交付剩余数量 × 所选模型的国费地方费其实现位于 estimate.js 的estimateModelEquivalent当剩余数量或单台补贴额不是有限正数时返回exact_available: false、exact_amount_krw: null的不可用预算结构否则用remainingCount * subsidyPerVehicleKrw取整并在estimate_assumptions中写明三条假设全部剩余数都分配给所选模型、按确认的国费地方费计算、不含按购买者特征的追加支持与对象群间数量转换。因此该换算值不是地方自治团体的精确预算余额模型别金额、购买者追加支持、数量转换、受理后的预约/取消都会使其偏离实际可用预算。回答用户时必须明确这是换算值/估算而非精确可用金额这也是下一条工作流的基本原则。工作流五保守作答的输出规范最终答复必须包含原指令 Workflow 第 5 步地区、车种、基准年份民间公告/受理/交付/交付剩余四项数量公告状态与备注核心语句若有模型换算值说明计算假设固定警告语출고잔여대수는 실제 신청 가능 대수 및 정확한 원화 잔액과 다를 수 있음交付剩余数量可能与实际可申请数量及精确韩元余额不同官方来源 URL 与 KST 查询时间。CLI 的formatStatus默认输出已经内置了以上要素包括末尾的注意语与출처: source.url行--json模式下则由调用方按相同规则组织。在exact_availablefalse的场景必须同时给出原因不能把估算伪装成事实。可选浏览器路径诊断与模型查询的兜底默认direct-http无需浏览器但在两种情况下可显式切换到浏览器传输官方页面结构变更需要诊断或需要更可靠地读取模型别换算值。命令示例npx ev-subsidy-status status --region 경기 성남시 --transport browser --provider aside npx ev-subsidy-status status --region 경기 성남시 --transport browser --provider browseros npx ev-subsidy-status status --region 경기 성남시 --transport browser --provider chrome-cdp浏览器路径的行为约束原指令 Optional browser behavior非常严格在domcontentloaded事件后显式等待目标选择器与地区行出现不使用networkidle等待策略——因为pnp4web有后台请求networkidle 会导致永久等待通过渲染后的option的 label/value动态解析地区代码不关闭用户既有的标签页与配置文件profile只清理技能自己创建的页面/上下文并仅对受支持的 client 执行 disconnect绝不绕过登录、CAPTCHA、支付、电子签名、最终提交等边界。浏览器接入基于k-skill-browser-runtime见 package.json 的依赖声明连接用户已启动的 Aside Browser、BrowserOS 或 Chrome CDP 会话若没有可连接的浏览器则报BROWSER_UNAVAILABLE。错误包装逻辑errors.js 的wrapBrowserError会把上游CAPTCHA_DETECTED、AUTH_REQUIRED、UNKNOWN_PROVIDER、UNAVAILABLE/PLAYWRIGHT_UNAVAILABLE分别映射为技能级错误码其余统一归为UPSTREAM_FAILED并保留upstream_code便于排查。完成标准Done when一次成功的查询应满足请求的地区与车种与官方表格中的行一致返回公告/受理/交付/交付剩余数值与地方自治团体备注显式截止语句优先于正数剩余数量无法确知精确韩元预算余额时返回exact_availablefalse并说明原因展示来源 URL 与 KST 查询时间。失败模式全表技能以稳定错误码暴露全部异常原指令 Failure modes与 errors.js 及 http.js 的实现一致错误码触发条件REGION_REQUIRED未提供地区输入REGION_AMBIGUOUS同名市郡区出现在多个市道需用户指定市道REGION_NOT_FOUND地区不在官方地区选项中YEAR_NOT_AVAILABLE请求年份不在页面选择列表中VEHICLE_TYPE_NOT_AVAILABLE请求的车种不受支持或页面中找不到BROWSER_UNAVAILABLE没有可连接的用户浏览器UPSTREAM_BLOCKED官方返回空壳、拦截或异常页面CAPTCHA_DETECTED出现 CAPTCHA技能不绕过AUTH_REQUIRED公开页面变为登录流程技能不绕过RESULT_EMPTY目标地区无结果行DOM_CHANGED官方页面选择器或表格结构变化UPSTREAM_DECODE_FAILEDpnp4web字符表或保护 payload 格式变化MODEL_LOOKUP_FAILED模型别补贴表读取失败UPSTREAM_TIMEOUT官方站点响应超时默认超时 30000ms见 http.jsCLI 出错时以 JSON 输出{ error: { code, message, details } }formatError便于 Agent 或上层脚本结构化处理EvSubsidyError实例携带code、message、details与可选cause。测试与质量保障该技能在仓库中配有完整测试node --test驱动 test/index.test.js、test/http.test.js、test/browser.test.js覆盖状态聚合、HTTP 解码链路与浏览器行为lint脚本对所有源码与测试文件做node --check语法校验。感兴趣的可直接运行cd packages/ev-subsidy-status npm test总而言之ev-subsidy-status 的价值在于把被脚本保护的官方公开数据安全、可重复、无浏览器地转化为结构化 JSON先归一化地区与车种再以备注优先判定公告状态最后在需要时给出带假设说明的模型换算值——整个过程对上游格式变化以明确错误码快速暴露保证了查询结果的可审计性与数据真实性。【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考