k-skill 实战:基于 RELAY_STORE 与 JSON-LD 构建 당근부동산(胡萝卜房地产)只读房源搜索技能
2026/9/16 20:50:58 网站建设 项目流程

k-skill 实战:基于 RELAY_STORE 与 JSON-LD 构建 당근부동산(胡萝卜房地产)只读房源搜索技能

【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill

本指南以 k-skill 仓库中daangn-realty-search技能文档为核心,完整讲解如何在 Agent 中通过公开网页数据表面实现韩国 당근부동산 的只读房源候选检索、区域解析与详情补全。读完本文,你将掌握window.RELAY_STORE(Relay 归一化 Store) 的双重解码解析技巧、application/ld+json结构化数据抽取方法,以及一套可直接复制运行的 Python 标准库命令行搜索方案,并理解其合规边界与失效模式。

技能定位:读什么、不做什么

daangn-realty-search是 k-skill 仓库中面向韩国房地产检索场景的技能,其核心定义在 docs/features/daangn-realty-search.md:

당근부동산 공개 웹 데이터 표면을 사용해 지역 기반 부동산 매물 후보를 검색하고, 상세 페이지의 공개 메타를 읽기 전용으로 확인하는 스킬입니다.

即:只用公开网页数据表面完成「按区域搜索房源候选」与「读取详情页公开元数据」两步,不做浏览器自动化、登录、聊天、询价、预约、签约等任何会对外部服务产生副作用的行为。这一点在 instruction.md 的 "When not to use" 中明确列出:需要登录、涉及聊天/收藏/交易提议/预约/签约/购买、需要绕过 CAPTCHA/反爬/登录墙的任务都明确不在本技能范围内。

典型使用场景(来自原文档):

  • 「당근부동산 합정동 월세 매물 찾아봐」(帮我在合井洞找月租房源)
  • 「마포구 전세 후보 당근에서 봐줘」(在 당근 上看麻浦区全租候选)
  • 「이 당근부동산 URL 상세 요약해줘」(总结这个 당근부동산 URL 详情)

技能元数据(skill.json)标注category: real-estatelocale: ko-KRphase: v1.5,主程序仅依赖 Python 3.9+ 标准库(urllib/json/re/argparse),不引入任何第三方包。

三个数据表面与 2026-06 域名迁移应对

实现全部基于浏览器公开渲染结果的只读抓取,instruction.md 将数据表面整理为三层:

表面端点用途
区域解析https://www.daangn.com/kr/api/v1/regions/keyword?keyword=<지역명>返回{"locations":[{id,name1,name2,name3,name*Id,depth}]}
房源列表https://realty.daangn.com/map/{name1}/{name2}/{name3}SSR 注入的window.RELAY_STORE
房源详情https://realty.daangn.com/articles/<id>application/ld+json<title>

需要特别注意的是旧版表面的废弃:原文档明确警告,旧版https://www.daangn.com/kr/realty/?_data=routes/kr.realty._index表面自 2026-06 起返回 HTTP 204(空响应),已彻底弃用、禁止再使用。源码 daangn_realty.py 的模块 docstring 也记录了这次域名迁移的应对:新表面统一指向realty.daangn.com/map/{name1}/{name2}/{name3}并解析其中的window.RELAY_STORE

RELAY_STORE 解析路径:Card 优先的稳健策略

window.RELAY_STORE是页面 SSR 时注入的 Relay 归一化 Store。文档给出的理论解析路径为:

ArticleFeedConnection.edges → ArticleFeedEdge.node → ArticleFeedCard.article → Article

但 daangn_relay_store.py 的实际实现采用了更稳健的策略:直接遍历 Store 中所有__typename == "ArticleFeedCard"的节点,再对article引用解引用(deref)。源码注释解释了原因:Store 中 Card 是直接平铺存放的,绕开 edges 链可以少走一层引用跳转,容错性更强。

双重 JSON 解码:字符串再字符串

这是本技能最值得注意的底层细节。window.RELAY_STORE在 HTML 中是以JS 转义字符串形式存在的,源码extract_relay_store用正则捕获后执行:

return json.loads(json.loads('"' + match.group(1) + '"'))

json.loads(json.loads(...))两级解码:第一级把转义字符串还原为原始 JSON 文本,第二级把文本解析为对象。仓库测试 test_daangn_realty.py 中构造测试 HTML 时同样用json.dumps(json.dumps(store))双层编码来模拟真实页面,验证了这条路径。若双层 JSON 解码失败,函数返回None,由上层按「页面结构变更或反爬」处理。

字段提取与价格单位

Article节点上关键字段(daangn_relay_store.py):

  • originalId→ 文章 ID,拼出详情 URLhttps://realty.daangn.com/articles/<id>
  • area→ 面积(㎡),可能是字符串,必须float()转换(源码_parse_areaNone/空串/非法值均安全降级)
  • salesTypeV3→ 解引用后取type(如OFFICETEL
  • trades→ 引用数组,按__typename分派解析

价格单位 = 만원(万韩元),这是阅读输出时必须牢记的换算规则:

字段含义示例含义
deposit保证金/全租押金2000 = 2,000만원(2千万韩元)
monthlyPay月租金100 = 100만원(100万韩元)
price买卖价28700 = 2억8,700만원

交易类型与평당(每坪)单价

三种交易类型由__typename区分(daangn_relay_store.py):

交易类型typename价格字段평당单价
월세(月租)MonthTradedeposit + monthlyPaymonthlyPay / 평
매매(买卖)BuyTradepriceprice / 평
전세(全租)BorrowTradedepositdeposit / 평

其中평 = ㎡ / 3.305785,源码常量PY_PER_SQM = 3.305785。测试用例验证了换算正确性:33.05785㎡ → 10평,月租monthlyPay=50时 평당单价 = 5.0만원。salesType枚举取值包括APARTOFFICETELSTOREOPEN_ONE_ROOMSPLIT_ONE_ROOMTWO_ROOMHOUSE等。

详情补全:JSON-LD 结构化数据抽取

列表页不含楼层、标题、地址,需要访问详情页https://realty.daangn.com/articles/<id>补全。解析逻辑在 daangn_detail_ld.py:

  • 用正则抽取所有<script type="application/ld+json">
  • 兼容@graph数组/对象/单节点多种形态(_json_ld_nodes
  • @type == "Product"节点取name(标题)、releaseDate(发布日期, ISO 8601 UTC)
  • @type == "Place"节点取name(地址)
  • additionalProperty数组按name匹配提取floortopFloornearbySubwayStation

楼层最终格式化为floor_label,例如floor="8.0"+topFloor="10""8층/10층"(源码会把.0后缀剥掉)。测试用例 test_daangn_realty.py 完整覆盖了该路径,包括@graph: null的容错、releaseDate 缺失默认None、以及后续 Product 节点优先覆盖 releaseDate 的行为。

命令行使用与参数详解

技能文档给出了三条核心命令,全部通过 k-skill CLI 执行:

# 基础搜索(补全前 5 条标题/楼层) npx -y @nomadamas/k-skill@0 exec daangn-realty-search scripts/daangn_realty.py -- search --region "합정동" --limit 5 # 组合过滤(用途 + 交易类型) npx -y @nomadamas/k-skill@0 exec daangn-realty-search scripts/daangn_realty.py -- search --region "합정동" --sales-type "STORE,OFFICETEL" --trade-type "MONTH" # 详情页解析 npx -y @nomadamas/k-skill@0 exec daangn-realty-search scripts/daangn_realty.py -- detail "https://realty.daangn.com/articles/..."

search子命令的全部参数(daangn_realty.py):

参数默认值说明
--region必填洞名(如 매교동、합정동)
--sales-type用途过滤,逗号分隔,如STORE,OFFICETEL
--trade-type交易过滤,逗号分隔:MONTH(月租)/BUY(买卖)/BORROW(全租)
--limit20最大返回条数
--titles5用详情 JSON-LD 补全标题/楼层的前 N 条;0关闭(更快)
--expand扩展到同区/市相邻洞搜索
--expand-max6扩展时相邻洞最大数量
--keyword兼容旧 CLI 的关键字过滤(对返回物料的公开字段文本过滤)
--only-verified兼容旧 CLI 的认证标记(公开 feed 不提供单独认证字段,仅兼容保留)

其中--titles 0是追求速度的常用技巧——省去对每条候选发起详情页请求;而--expand则依赖区域解析的name2Id做兄弟洞聚合(见下节)。

区域解析与 effective_region

区域名通过 region API 解析为内部对象后填入地图 URL 路径:

합정동 → 서울특별시 마포구 합정동 → /map/서울특별시/마포구/합정동

源码resolve_region(daangn_realty.py)的候选排序策略是:精确匹配 → 首尔 depth=3 → 首个候选。当存在同名洞时按此优先级消歧。响应中会包含effective_region(最终生效的完整行政区划名)。

--expand的实现思路是:用name2(구/시) 关键词再次请求 region API,收集name2Iddepth == 3的相邻洞(find_sibling_regions),对每个洞分别抓取列表页后按article_id去重合并,最终按--limit截断。这正是「수원 팔달구 상가 매물 봐줘」这类跨洞检索诉求的支撑。

输出字段解读与判断要点

搜索输出为 JSON,单个物料字段如下(instruction.md):

article_id, salesType, area_sqm, area_pyeong, trades[{type,label,deposit_manwon,monthly_manwon,price_manwon,per_pyeong_manwon}], url, region, title, address, floor_label, nearby_subway, release_date

原文档强调:做房地产判断时,实时状态、保证金/月租、管理费、面积、是否中介/直营是关键信息,因此输出会连同原始 URL 一起给出,供最终核实。此外:

  • release_date来自详情页 JSON-LD 的Product.releaseDate(ISO 8601, UTC),只对--titles补全范围内的物料填充;它究竟是首次登记日还是最近刷新/修改日,당근 侧并无公开规范,不能断定。
  • 顶层响应还包含effective_regionexpandregions_searchedsources(每洞 URL+条数+note)、errors字段,便于审计搜索覆盖面。

失效模式与合规边界

原文档明确了三类失败模式,源码中均有对应处理:

  1. RELAY_STORE 없음:页面结构再次变更或触发反爬,此时extract_relay_store返回None,上层在sources[].note中记录并不尝试绕过
  2. 시군구(name2) 落地页无物料:列表必须精确到洞(name3)层,SSR 才会填充 articleFeed;只到区/市层拿不到候选。
  3. 同洞歧义与详情失效:同洞名可能选中不同行政洞;删除/私密文章详情解析会失败(parse_detail返回各字段为None的结构)。

合规层面必须遵守仓库内 DISCLAIMER.md 与 SKILL.md 的硬性规则:

  • 公开信息自动收集仅限个人查询用途,禁止组织化、系统化、批量爬取及数据库构建/再分发;
  • 禁止绕过登录墙、付费墙、CAPTCHA、访问控制、限流与 IP 封锁,检测到拒绝/封锁信号立即停止;
  • 不执行任何支付、消息发送、最终提交、取消或公开发布动作,除非用户在操作前明确批准;
  • 该技能与 당근 官方无任何从属、赞助或合作关系(非官方功能)。

最小运行条件与后续阅读

  • 运行前提:联网 + Python 3.9+,且npx可用(Node.js 18+);若npx不可用,可通过npx -y @nomadamas/k-skill@0 instruct daangn-realty-search获取完整说明。
  • Windows 下中文/韩文 stdout 乱码防护:支持运行时中脚本会执行sys.stdout.reconfigure(encoding='utf-8')(daangn_realty.py)。

想深入底层验证,可继续阅读:daangn_relay_store.py(Store 解析与交易分派)、daangn_detail_ld.py(JSON-LD 抽取)、test_daangn_realty.py(含 mock 的完整测试矩阵),或通过npx -y @nomadamas/k-skill@0 files daangn-realty-search查看随 CLI 分发的全部辅助文件。

【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询