
k-skill 之 danawa-price-search基于 다나와 公开比价表面的只读价格对比 Skill 实战解析【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill本文以 danawa-price-search/instruction.md 为主体完整讲解 k-skill 仓库中 다나와Danawa价格对比 Skill 的能力边界、三个公开 HTTP 表面、三条 CLI 命令及其 JSON 输出契约并结合 danawa-price-search/scripts/danawa_search.py 源码与 scripts/test_danawa_price_search.py 测试深入解析「결제조건支付条件徽章白名单」与total_price单标准排序的实现原理帮助读者掌握一个可复制、可验证的登录无关login-free商品比价 Agent 技能。1. Skill 定位与能力边界该 Skill 属于 k-skill한국인을 위한 스킬 모음집 — 把 Agent 变成韩国人的技能集合中retail类别、ko-KR语区的技能元信息见 danawa-price-search/skill.json 与 danawa-price-search/SKILL.mdcategory: retail、locale: ko-KR、phase: v1profile 为action:commerce。它只做一件事以只读方式调用 다나와의 로그인 없는 공개 검색/가격비교 표면다나와 的无登录公开搜索/价格对比表面实现韩国各商城价格的比较。具体能力包括通过商品名/检索词找到 다나와 的商品候选与pcode商品编号查询选定商品在各商城쇼핑몰별的 offer 列表不止商品价还把含运费的实付价배송비 포함 실구매가、是否免费配送、卡片折扣价、无息分期무이자 할부文案一并整理明确不做购买、登录、购物车、收藏찜、下单等任何写操作。适用与不适用场景When to use / When not to use适用的典型用户请求文档原文列举다나와에서 에어팟 최저가 찾아줘在 다나와 上找 AirPod 最低价다나와 가격비교로 쇼핑몰별 가격 비교해줘用 다나와 价格对比做商城间价格比较무료배송인지, 카드 할인까지 보면 어디가 제일 싸?看免费配送、卡片折扣后哪里最便宜무이자 할부 붙은 최저가도 같이 봐줘把带无息分期的最低价也一起看看明确不适用的场景需要实际购买/下单/支付/登录的场景需要确认会员专属优惠券、个性化积分、App 专属福利的场景需要大批量监控或高频爬取的场景出现 CAPTCHA、访问封锁需要绕过 fingerprint 的场景。必需输入唯一必需输入是商品名或检索词。当检索词过于宽泛时Agent 应主动追问品牌、型号、容量、颜色、自购机/运营商合约机等限定条件。文档给出的推荐提问模板찾을 다나와 상품명이나 모델명을 알려주세요. 예: 갤럭시 S25 울트라 256GB 자급제, 에어팟 프로 2세대 USB-C 请告诉我您要查找的 다나와 商品名或型号。例Galaxy S25 Ultra 256GB 自购机、AirPod Pro 2 代 USB-C2. 三个公开表面Public surfaces当前实现只使用无认证인증 없음的公开表面共三个端点用途端点搜索页https://search.danawa.com/dsearch.php?query...商品详情页https://prod.danawa.com/info/?pcode...价格对比 AJAXhttps://prod.danawa.com/info/ajax/getAllPriceCompareMallList.ajax.php其中 AJAX 端点返回 HTML 片段fragmenthelper 从其中解析.diff_item、商城 logo 的alt属性、em.prc_c/em.prc_t价格元素、配送文案、支付条件徽章.ico.cash/.ico.point/.ico.coupon/.ico.discount/.ico.card/.ico.membership等、卡片折扣行、无息分期图层以及 다나와 桥接链接bridge link。源码层的请求细节从 danawa_search.py 的fetch()实现L29-L43可以看到几个关键实现事实固定桌面 Chrome 的User-Agent与Accept-Language: ko-KR请求头POST 请求即 AJAX 价格列表调用会附加Content-Type: application/x-www-form-urlencoded、X-Requested-With: XMLHttpRequest并带上详情页Referer见offers()中fetch(..., methodPOST, datadata, referermeta[source_url])L186——这与浏览器真实 AJAX 行为一致是该端点可匿名访问的关键前提统一 25 秒超时解码失败用replace容错。search()L73-L108解析搜索页的li.prod_item列表项从#min_price_{pid}输入框的value取值作为最低标价取不到时回退.price_sect strong/.prod_pricelist strong并从li的idproductItem{pcode}中剥离出pcode。product_meta()L130-L152则用正则js_value()从详情页 HTML 中抽取内联 JS 变量nCategoryCode1~4、powerLinkKeyword、nMinPrice、sNaPm、sProductName、makerCode/makerName等再作为后续 AJAX 调用的表单字段——从源码结构看AJAX 端点要求携带这些从详情页抓取的上下文字段才能正确返回商城列表。3. 三条 CLI 命令命令在技能目录下通过 k-skill CLI 执行npx需要 Node.js 18SKILL.md也说明了npx -y nomadamas/k-skill0 instruct danawa-price-search获取完整说明、files danawa-price-search列出随附 helper 的用法npx -y nomadamas/k-skill0 exec danawa-price-search scripts/danawa_search.py -- search 에어팟 프로 2세대 --limit 8 npx -y nomadamas/k-skill0 exec danawa-price-search scripts/danawa_search.py -- offers 28208783 --limit 10 npx -y nomadamas/k-skill0 exec danawa-price-search scripts/danawa_search.py -- compare 에어팟 프로 2세대 --limit 5 --offers 5helper只输出 JSON。查看结果后再向用户以韩文表格 简短结论的形式总结。结合源码main()的参数定义L324-L350各子命令的完整参数如下子命令位置参数选项默认值源码searchquery检索词--limit候选数正整数110offerspcode商品编号--limit返回 offer 数正整数20--include-shipping布尔开关对应 AJAX 表单bPostPriceYNY/N关闭comparequery检索词--limit搜索候选数 /--offers每候选的 offer 数5 / 5错误处理任何异常会以{error: ...}形式输出到 stderr 并返回退出码 2L348-L350调用方可据此判定失败。4. 输出契约Output shape4.1search输出{ query: ..., source_url: ..., count: 0, items: [] }items[]的主要字段源码 L94-L105 构造pcode— 商品编号后续offers的输入title— 商品名price/price_text— 最低标价整数 / 千分位韩元文案mall_text— 商城文案.prod_pricelist .memory_sect或.meta_itemurl— 商品详情页链接abs_url()会把//前缀补全为 https、把站内绝对路径挂到https://prod.danawa.com下image_url— 缩略图优先data-original懒加载属性spec— 前 10 个.spec_list a/span的规格文本拼接截断至 300 字符。4.2offers输出{ pcode: ..., title: ..., source_url: ..., count: 0, normal_count: 0, conditional_count: 0, offers: [], meta: { sort: total_price } }核心排序约定offers[]按含运费实付价total_price升序单一标准排序。count/normal_count/conditional_count统计的是应用limit之后实际返回的offers[]窗口。带支付条件现金/优惠券/积分/折扣/特定卡片/会员限定的行不参与分组或过滤直接参加同一排序——最便宜就排第一。支付条件通过行内字段暴露由调用方按用户支付手段自行判断。offers[]各字段与源码 L243-L271 一一对应mall— 商城名取自.d_mall img的altprice/price_text— 商品标价shipping— 配送文案原文is_free_shipping— 文案含 무료 即视为免费配送shipping_fee— 运费数值免费为 0解析失败为 nulltotal_price/total_price_text—price shipping_fee的实付价card_price/card_price_text— 卡片适用价.card_line .card_prccard_name— 卡片名.card_line .txtcard_discount/card_discount_text— 标价与卡片价的差额installment/installment_detail— 无息分期按钮文案.btn_foi .txt与分期图层详情.foi_layer .ly_contpayment_badges— 다나와 在价格旁展示的支付条件徽章的显示标签列表即使徽章文本为空、只有.ico.cash这类纯类名也会按白名单合成显示标签如[현금]、[포인트]、[쿠폰]、[카드]、[할인]、[멤버십]payment_condition_types— 白名单徽章归一化后的条件类型列表cash/point/coupon/card/discount/membershippayment_condition_label— 面向用户的支付条件标签如현금、할인、멤버십多条件时현금, 할인cash_only/point_only/coupon_only— 现金专用价 / 积分抵扣价 / 优惠券适用价card_only_badge/discount_badge/membership_badge— 特定卡片限定 / 折扣条件 / 会员条件徽章曝光价is_conditional_price—payment_condition_types非空即为 True表示这不是普通支付价普通卡片支付时价格可能不同甚至不可用url— 다나와 桥接链接。文档特别强调必须同时查看免费配送、含运费实付价、卡片折扣价、无息分期文案以及payment_badges/payment_condition_label/is_conditional_price。如果把条件价当普通价放第一位比价结果就是误导。4.3compare输出compare先取搜索结果再对每个候选商品 best-effort 地附上offers[]。源码实现L300-L314中单个候选的详情调用抛异常时不会中断整体流程而是把异常记入该行的offers_error字段meta.detail_extraction标记为best-effort。当搜索结果含糊同名不同规格混排时应先展示前 3~5 个候选的标题与pcode请用户选择。5. 支付条件徽章解析白名单设计与源码级原理这是该 Skill 最有技术含量的部分。다나와 的 offer 行里会混排多种图标快速配送、商品提示、评论入口等其中只有支付条件类徽章才影响价格语义。offers()中的处理逻辑L206-L242只扫描支付条件徽章区域选择器限定为.prc_line .ico, .d_dsc .ico源码注释明确其他 ico빠른배송、안내、상품리뷰 等是噪声予以排除类名 文本双通道匹配白名单表payment_condition_labels为cash→현금、point→포인트、coupon→쿠폰、card→카드、discount→할인、membership→멤버십。只要元素的 CSS 类包含类型名如.ico.cash或文本包含韩文标签即命中——因此类名有、文本空和文本有、类名无两种形态都能被捕获统一派生四个层面payment_condition_types归一化类型、payment_badges显示标签、行内布尔标志cash_only等、is_conditional_price。这一设计的验证在 scripts/test_danawa_price_search.py 中相当完整测试通过 mockproduct_meta与fetch注入构造好的.diff_itemHTML 片段test_class_only_payment_badges_synthesize_display_labels六种纯类名徽章span classico cash/span等均正确合成显示标签、类型、布尔字段与is_conditional_priceTruetest_payment_badges_are_deduped_with_canonical_class_orderspan classico cash/spanspan classico현금/spanspan classico card카드/span三个徽章去重后得到[현금, 카드]标签为현금, 카드test_non_payment_ico_is_not_capturedspan classico quick빠른배송/span不会被误判为条件价normal_count1test_cli_json_includes_normalized_payment_fields端到端验证 CLI 输出的 JSON 中包含归一化字段。运行入口测试按文件路径加载danawa-price-search/scripts/danawa_search.pyROOT parents[1]即仓库根可用python -m unittest scripts/test_danawa_price_search.py方式执行。排序实现的源码证据rows.sort(key...)L276-L281的排序键为total_price为 None 的行排后 →total_price缺省回退price→price→ 商城名。这与文档total_price오름차순 단일 기준升序单一标准完全对应meta.sort固定为total_price。normal_count/conditional_count在截断到limit之后统计L287-L289因此它们反映的是最终返回窗口的构成而非全量结果。6. 响应风格面向用户的表格与结论在 Discord/Telegram/聊天场景下优先使用表格instruction.md 原文示例| 순위 | 판매처 | 상품가 | 결제조건 | 배송 | 실구매가 | 카드할인가 | 무이자 | 링크 | |---:|---|---:|---|---|---:|---:|---:|---| | 1 | 킴스클럽 | 979,000원 | **현금 전용** | 유/무료 | 979,000원 | - | - | 보기 | | 2 | 롯데ON | 1,073,890원 | 일반 | 무료배송 | 1,073,890원 | - | - | 보기 | | 3 | G마켓 | 1,089,590원 | 일반 | 무료배송 | 1,089,590원 | - | 최대 24개월 | 보기 | | 4 | 옥션 | 1,121,780원 | **쿠폰 적용가** | 무료배송 | 1,121,780원 | 우리카드 303,720원 | 최대 24개월 | 보기 |排序与呈现规则单一标准total_price升序带支付条件的行同样参与排序最便宜就列第一不分组、不过滤只在결제조건列按行标注payment_condition_label优先显示否则일반。具体映射cash→현금 전용、coupon→쿠폰 적용가、point→포인트 적용가、card→卡片名/卡片条件、discount→할인 조건、membership→멤버십 조건若card_price存在且按卡片计价会改变胜者则在表下另写一行카드 기준 최저가按卡片计的最低价无息分期可能改变支付条件须注明以 다나와 曝光文案为准第 1 名是条件价时在摘要中简短补充支付手段限定并同时给出卡片支付口径的最低价让用户一次比完。摘要示例최저 실구매가: G마켓 217,950원 / 무료배송 카드 기준 최저가: 옥션 우리카드 303,720원 무이자: G마켓·옥션 최대 24개월 표기若页面上没有卡片折扣 markup应写카드 할인가 표기 없음无卡片折扣标示而不能据此断言结账时不存在任何折扣。7. 工作流Workflow文档定义的完整执行序列确认检索词用search 检索词 --limit 5查看候选候选明确则用对应pcode执行offers候选含糊则展示前 3~5 个的商品名/价格/pcode请用户选择offer 按total_price升序单标准排序不做支付条件分组条件价列第一也照实列第一只在表格列与行级标志中标注有卡片折扣价时另写卡片口径最低价第 1 名是条件价时摘要中一并给出카드 결제 기준 최저가附注以查询时点为准价格/配送/卡片权益可能变动。8. 失败模式与降级策略Failure modes搜索 0 结果把检索词改具体加品牌、型号、容量等다나와 HTML/AJAX 结构变化selector 失效会导致offers为空或字段缺失白名单需随站方演化维护若다나와引入新的支付条件徽章类名或文案必须同步更新徽章白名单cash/point/coupon/discount/card/membership类名 현금/포인트/쿠폰/할인/카드/멤버십文本关键词以及payment_condition_types/payment_condition_label映射——这也是第 5 节白名单设计的维护面搜索结果价格与 offer AJAX 价格可能不一致刷新时点、卡片价、联盟链接口径差异卡片折扣与无息文案只有在 다나와 实际曝光时才确定性地呈现基于公开表面高频请求应自行加入 throttling/backoff出现访问封锁或 CAPTCHA不尝试绕过按失败模式上报。9. 完成判据与合规边界Done when完成判据已确认检索词/型号至少返回 1 个商品候选或说明了失败原因已按时点口径整理各商城的商品价、运费、实付价、卡片折扣价与无息文案用户响应为表格形式全程未越出登录/购买/绕封锁的边界。合规方面danawa-price-search/SKILL.md 列出了三条硬性规则即使没有 CLI 也必须遵守未经用户在操作前明确批准绝不执行支付、消息/邮件发送、最终提交、取消或公开发布绝不索取、打印或存储明文凭据绝不绕过 CAPTCHA、身份验证、电子签名等边界。完整的韩国法务声明含大法院判例与法条引用见 danawa-price-search/references/DISCLAIMER.md商标声明见 danawa-price-search/references/TRADEMARK-LEGAL-STATEMENT.md。此外本 Skill 与任何被提及的第三方商标持有人或服务运营方均无官方关系自动化采集仅限个人、非组织用途的查询不得用于系统性/批量爬取、建库或绕过访问控制。10. 小结这个 Skill 的工程要点从 instruction.md 与源码的对照可以看出该 Skill 的设计要点可以归纳为四条表面最小化只依赖 3 个无认证公开端点POST AJAX 通过复刻浏览器请求头X-Requested-With、Referer、详情页内联 JS 变量表单字段实现匿名调用单一排序标准 行级条件标注total_price升序不分組支付条件全部下放到行内字段payment_badges/payment_condition_label/is_conditional_price及六个布尔标志把哪个价最便宜和这个价对我不适用的判断分别交给排序与展示层白名单驱动的条件徽章解析类名/文本双通道匹配 纯类名徽章合成标签配合单元测试锁定行为是应对站方 HTML 结构漂移的可维护设计只读与失败透明不执行任何写操作异常走 stderr JSON 退出码 2compare的详情失败降级为行级offers_errorCAPTCHA/封锁直接上报而非绕过。更多实现背景可参考 docs/features/danawa-price-search.md场景、实现表面、本地运行与字段说明以及 danawa-price-search/skill.json 中的技能元数据。适用前提提醒该实现针对当前다나와公开页面结构若站方改版selector 与徽章白名单需按第 8 节所述同步维护所有价格结论均应以查询时点为准。【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考