
如何稳定查询韩国法院不动产拍卖公告k-skill court-auction-notice-search 反爬与三条查询路径实战【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill用户问了一句明天首尔中央地方法院有哪些不动产拍卖要回答它得先摸到韩国大法院运营的 법원경매정보 网站courtauction.go.kr。但这个站点没有公开的 Open API而且对自动化流量极其敏感。k-skill 仓库里的court-auction-notice-search技能就是为这个场景做的一个只读、保守、慢即是稳的不动产拍卖公告查询客户端把法院公开的 매각공고拍卖公告与 사건案件信息翻译成 Agent 能直接消费的结构化 JSON。本文完整拆解它的三条查询路径、分层传输、限流预算机制和反爬防护设计。能力地图它做什么又明确不做什么先划清边界才能判断这个技能该不该用。✅ 能做的能力说明公告列表 展开按 매각기일拍卖日期·法院·기일/기간입찰期日/期间投标查 매각공고并把每张卡片展开成案件号、用途、地址、감정평가액评估价、최저매각가最低拍卖价案件号直查法院 案件号如2024타경100001一步查案件信息、物件明细、各拍卖日程、배당요구종기分配请求终期自由条件检索按地区·用途·价格带·评估价·面积·유찰횟수流拍次数·拍卖日期组合搜索物件代码表60 个 법원사무소法院事务所代码、投标区分、用途/地区代表代码全部可离线拿到反爬防护调用间隔 ≥2 秒 随机抖动、每会话调用预算、ipcheckfalse立即熔断❌ 明确不做的场景原因动产汽车·工程机械拍卖v1 范围只覆盖不动产某个拍卖日所有法院日程一次拉全属于后续跟进议题日历式查询物件照片 URL、명세서/감정평가서明细书/评估书PDF 下载后续跟进议题自动填写、自动提交投标书硬性红线投标必须由人在法院完成一句话定位参考用工具。查到的是公告时点的公开数据真实出价前必须回法院原公告复核。数据链路从검색按钮到归一化 JSON这条链路的核心事实是官网的搜索按钮背后并没有 REST API而是 WebSquare 框架的 JSON XHR 接口。技能做的事情就是替按钮按下去。用户条件 → 请求体构造 → warmup GET(拿会话 Cookie) → POST XHR endpoint → 原始 JSON → normalize.js 归一化 → 结构化结果技能直接调用的 5 个内部 endpoint定义在 src/transport/http.js 的ENDPOINT_PATHS常量里用途endpoint请求体核心键公告列表POST /pgj/pgj143/selectRletDspslPbanc.ondma_srchDspslPbanc.{srchYmd, cortOfcCd, bidDvsCd, srchBtnYn:Y}公告详情展开POST /pgj/pgj143/selectRletDspslPbancDtl.ondma_srchGnrlPbanc.{cortOfcCd, dspslDxdyYmd, jdbnCd, ...}案件单条POST /pgj/pgj15A/selectAuctnCsSrchRslt.ondma_srchCsDtlInf.{cortOfcCd, csNo}物件自由检索POST /pgj/pgjsearch/searchControllerMain.ondma_pageInfodma_srchGdsDtlSrchInfocanonical body由真实浏览器提交捕获见 test/fixtures/canonical-search-body.json法院代码表POST /pgj/pgjComm/selectCortOfcCdLst.on{}几个容易被忽略的工程细节warmup 先行。每次 POST 前会先 GET 对应的公告/检索页面把Set-Cookie收进自己的 cookie jar。会话过期导致的UPSTREAM_ERROR多数时候从 warmup 重新走一遍就好。请求头仿真。X-Requested-With: XMLHttpRequest、韩语优先的Accept-Language: ko-KR,ko;q0.9,en;q0.8并按 endpoint 动态拼Referer——每个 endpoint 都有自己对应的 Referer 提示路径伪装得不像真实页面跳转就会被怀疑。金额清洗。上游返回的金额常带 HTML 标签和千位逗号src/normalize.js 里的parseAmount会剥标签、去逗号、转成韩元整数日期统一成YYYY-MM-DD时间1430变14:30。自由检索响应的items[]还会做一层 raw 列名→英文键的映射节选raw 列归一化键saNocaseNumbersrnSaNo/printCsNo→displayCaseNumbergamevalAmt/minmaePriceappraisedPrice/minimumSalePricehjguSido hjguSigu hjguDong daepyoLotno buldNmaddressyuchalCnt/mulStatcd/jinstatCdflbdCount/statusCode/progressStatusCodelcls/mcls/sclsUtilCdusageCodes.{large,medium,small}xCordi/yCordi/wgs84Xcordi/Ycordicoordinates/coordinatesWgs84pjbBuldList/mulBigopropertyDescription/remarks三种问法三条路径把三条查询线理解成问题由浅入深的三个层次先找公告、再追案件、最后按条件挑物件。路径一哪天哪个法院有拍卖——公告列表 → 展开这是最常见的入口。调用searchSaleNotices({ date, courtCode, bidType })拿到某月某法院的公告卡片用户挑中一张后把整个卡片对象含raw原样传给getSaleNoticeDetail(notice)items[]里就有caseNumber、usage、address、appraisedPrice、minimumSalePrice、remarks。为什么必须原样传因为详情请求体里要带jdbnCd——一个列表响应才返回的加密令牌外部凭空构造不出来。构造逻辑在 src/index.js 的buildNoticeDetailBody里优先从列表行的raw里抽cortOfcCd、dspslDxdyYmd、jdbnCd、bidDvsCd抽不到才回落到显式入参。输入参数上的宽容度比直觉高都在src/index.js的校验函数里参数约束宽容行为date必填月YYYY-MM/YYYYMM或特定日YYYY-MM-DD/YYYYMMDD站点按钮本身按月查询特定日输入 月查询后本地按日过滤courtCodeB000210形式正则^B\d{6}$留空 全部法院bidTypedate기일입찰000331/period기간입찰000332기일입찰、000331等别名都认空值 两种都查caseNumber推荐2024타경1000012024-100001、2024_100001自动规范化路径二这个案子走到哪一步了——案件号直查给法院代码 案件号调getCaseByCaseNumber。两种返回found:false/status:204案件不存在或非公开。别重试请用户核对案件号格式与所属法院。found:truenormalizeCaseDetailResponse会把原始响应摊平成一套很完整的结构——caseInfo案件名·受理日·请求金额·裁判部·状态、items[]拍卖目的物·地址·分配请求终期、schedule[]每个拍卖日的最低价/评估价/结果、claimDeadline、relatedCases相关案件、appeals上诉/再上诉、stakeholders利害关系人。足够支撑后面还有几次拍卖分配期什么时候截止这类追问。路径三帮我按条件挑房子——自由条件检索最难的一条线因为站点 WAF 对它最严格。用户条件映射到searchProperties()输入region: { sido, sigungu, dong }— 시도市道可传代码或韩语名静态表 19 行시군구/읍면동 没有静态表直接传 raw 代码如{ sido:11, sigungu:11680, dong:11680101 }。给了 region 走 지번주소 搜索cortStDvs:2不给 region 走公告模式cortStDvs:1。usage: { large, medium, small }— 5 位代码20000건물或大分类韩语名토지/건물/차량및운송장비/기타。priceRange/appraisedPriceRange/area— 韩元或 ㎡ 的{ min, max }允许小数。saleDate: { from, to }、flbdCount: { min, max }只收整数。pageSize— 只能取10/20/50/100。传1这种值 live endpoint 直接 HTTP 400所以本地就先拒了。两个值得留意的防御设计都在 src/codetables/index.jsfail-open 透传未知的用途/地区值不猜、不映射原样透传让用户看到上游报错而不是被静默污染。同名用途保护resolveUsageCode(아파트, large)这种名字只存在于其他层级的输入不会错拿 medium/small 的同名代码而是透传原文。为什么慢却稳限流、预算与封禁熔断这个站点的反爬是 IP 级的而且下手很重——大约 16 次调用/30 秒就触发 1 小时封禁。整个客户端的默认值都是围着这个事实配的CourtAuctionHttpClient构造器见 src/transport/http.js机制默认值实现位置调用间最小间隔2000msensureBudget()里与上次调用时间比较不够就补等随机抖动0~1000msjitter(min, jitterMs)在最小值上叠加随机增量避免机械等距每会话调用预算10 次超限抛BUDGET_EXCEEDED这是有意设计的安全阀单请求超时15000msAbortController超时即断封禁熔断data.ipcheck false立即抛BLOCKEDpostJson()末尾检测不自动重试重试只会延长封禁需要更保守或更激进时直接构造客户端注入const { CourtAuctionHttpClient, searchSaleNotices } require(court-auction-notice-search); // 拉大间隔、收紧预算、放宽超时 const client new CourtAuctionHttpClient({ minDelayMs: 3000, jitterMs: 2000, maxCallsPerSession: 5, timeoutMs: 30_000 }); const notices await searchSaleNotices({ date: 2026-04-27, client });三层传输HTTP 打底浏览器兜底正常路径下根本不需要浏览器。浏览器的出场时机只有两个且都发生在searchProperties()路径三里直接 HTTP 撞到WAF 型 HTTP 400UPSTREAM_ERRORstatusCode 400撞到BLOCKED且调用方显式传了fallbackOnBlocked: true——默认不重试因为那是站点的明确封禁信号。fallback 激活后的连接顺序Runtime 浏览器首选借k-skill-browser-runtime自动探测——macOS 上依次试 Aside Browser REPL → BrowserOS GUI CDP → Chrome/Chromium CDP其他平台先试 BrowserOS。可用providerbrowseros/aside/chrome-cdp、cdpUrl选项或KSKILL_BROWSER_PROVIDER、KSKILL_BROWSEROS_CDP_URL、KSKILL_ASIDE_COMMAND环境变量指定。本地 Playwright launchruntime 全够不着时chromium.launch({ headless })自起浏览器。依赖rebrowser-playwright或playwright-coreoptionalDependencies见 package.json。清理规则分得很细src/transport/playwright.js连的是用户自己的浏览器时只关 adapter 建的 page/context/tab再disconnectBrowser断开自动化客户端绝不关闭 BrowserOS/Aside/Chrome 的 profile本地 launch 的是自己起的浏览器page/context/browser 全部关闭;PLAYWRIGHT_UNAVAILABLE模块没装与UNKNOWN_PROVIDERprovider 名写错fail-closed 立即抛错UNAVAILABLE/probe 失败则自动降级到本地 launch传{ fallback: false }可整体关掉自动降级。经验值同一个 Playwright 客户端连续调用10~15 次间隔调用是稳定的要更高 burst就调用间加 3~5 秒 sleep 并换新客户端。两条上手线Node.js 与 CLINode.js 一把梭const { getCourtCodes, searchSaleNotices, getSaleNoticeDetail, getCaseByCaseNumber } require(court-auction-notice-search); async function main() { // 先拉法院代码表确认 courtCode const courts await getCourtCodes(); console.log(加载法院事务所 ${courts.count} 家); // 查某日某法院的公告卡片 const notices await searchSaleNotices({ date: 2026-04-27, courtCode: B000210, // 서울중앙지방법원 bidType: date }); console.log(매각공고 ${notices.count} 건); // 展开第一张卡片raw 里的 jdbnCd 会被自动带上 if (notices.items.length 0) { const detail await getSaleNoticeDetail(notices.items[0]); for (const it of detail.items) { // 展示时建议同时给韩元整数 亿/万换算 console.log(${it.caseNumber} [${it.usage}] 감정 ${it.appraisedPrice} / 최저 ${it.minimumSalePrice}); } } // 案件号直查 const c await getCaseByCaseNumber({ courtCode: B000210, caseNumber: 2024타경100001 }); if (c.found) console.log(c.caseInfo.caseName, 拍卖日程 ${c.schedule.length} 次); } main().catch((e) { if (e.code BLOCKED) { console.error(IP 已被封 1 小时换网络或稍后再试); } else { console.error(e); } process.exitCode 1; });公共 API 面README Public API 有全表四个查询函数之外还有searchProperties、getBidTypes/getUsageCodes/getRegionCodes三张代码表、resolveBidTypeCode/describeBidTypeCode辅助函数、两个客户端类、isPlaywrightFallbackAvailable()以及createBlockedError/createUpstreamError/createNetworkError三个错误构造函数。CLI 按子命令走二进制名与 npm 包同名全局标志--json默认、--pretty、--include-rawfalse、--timeout-ms、--min-delay-ms、--max-calls、-h定义见 src/cli.js。# 代码表法院 / 投标区分 / 用途 / 地区 court-auction-notice-search codes courts --pretty | head -40 court-auction-notice-search codes bid-types --pretty court-auction-notice-search codes usages --pretty court-auction-notice-search codes regions --pretty # 公告列表 court-auction-notice-search notices --date 2026-04 --court-code B000210 --bid-type date --pretty # 案件号直查 court-auction-notice-search case --court-code B000210 --case-number 2024타경100001 --pretty # 自由条件检索地区 用途 价格带 日期窗 court-auction-notice-search search --sido 서울특별시 --sigungu 11680 \ --usage-large 건물 --usage-medium 21200 \ --price-min 100000000 --price-max 500000000 \ --sale-from 2026-05-01 --sale-to 2026-05-20 --prettysearch子命令还支持--region 시도[:시군구raw[:읍면동raw]]、--usage 대[:중[:소]]、--appraised-min/max、--area-min/max、--flbd-min/max、--page、--page-size 10|20|50|100。公告详情这一步在单次 CLI 调用里可以用 jq 把 list 输出里的raw喂给notice-detail子命令串起来。出问题怎么办错误码表与常见坑错误码触发条件怎么处理BLOCKEDdata.ipcheck false立刻停。告诉用户封禁事实等约 1 小时换 IP 再试人工用浏览器走完站点解封画面也可以BUDGET_EXCEEDED会话预算默认 10 次用完有意的安全阀。确需更多就开新客户端或--max-calls 20同时把封禁风险说给用户UPSTREAM_ERROR站点返回一般性错误最常见根因是会话过期或jdbnCd 失效从 warmup 重新开始NETWORK_ERROR超时 / 连接失败原始异常在error.cause检查网络与timeoutMsPLAYWRIGHT_UNAVAILABLE想走 Playwright fallback 但模块没装npm i rebrowser-playwright或npm i playwright-core常见坑清单400 别慌路径三的 WAF 型 400 是预期内的降级触发点只要 Playwright 模块在位会自动切浏览器重试模块没装则原样抛出。特定日查不到站点按钮按月查2026-04-27这种输入是月查询 本地按日过滤当月该日确实无公告时返回空列表是正常的。pageSize只认 10/20/50/100本地强校验拦掉其他值别试图绕过。found:false不是故障案件号写错、法院代码对不上、案件非公开都会是这个结果——把后路指给用户。价格/日期以公告时点为准响应里的correctionCount、cancellationCount字段提示数据可能被更正、撤回或延期。错误对象本身的构造在 src/transport/http.jsBLOCKED携带upstreamUrl: courtauction.go.kr与upstreamPayloadUPSTREAM_ERROR从payload.errors.errorMessage里抽upstreamMessageNETWORK_ERROR把原始异常挂到error.cause。红线与诚实声明每次使用这个技能有四句话绕不过去数据是法원경매정보 站点公开信息的原样转述实际投标前必须重新核对法院原始公告站点对自动化非常敏感快速连续查询可能让 IP 被封 1 小时同一 IP 恢复前只能等价格감정평가액·최저매각가격、매각기일、매각장소以公告时点为准可能因 정정更正·취하撤回·연기延期变化技能是read-only不代填投标书不代提交投标只能由人在法院完成。Agent 侧还有几条通用硬红线见 SKILL.md 的 Hard rules未经用户明确即时批准绝不执行支付、消息/邮件投递、最终提交、取消、公开张贴绝不在聊天、文件或 shell 参数里明文保存凭据绝不绕过法律边界、物理到场要求、CAPTCHA、身份核验或电子签名——碰到这类环节完成最远合法步骤后把下一步官方操作精确准备好交给用户本人。验收清单与继续探索一次任务算完成自检这几项已向用户声明 IP 封禁风险与仅供参考、投标前核对原公告已返回带caseNumber/usage/address/appraisedPrice/minimumSalePrice的公告展开 JSON案件直查found:false时给了可执行的下一步指引遇封禁没有自动重试立即停下任务结束告知剩余调用预算让用户知道还有没有查询余量想验证包本身进 packages/court-auction-notice-search 跑npm run lint # node --check 全部源文件与测试 npm run test # node --test覆盖 index/normalize/transport/cli 四组推荐的文件阅读顺序instruction.md能力与规则总纲→ README.mdAPI 与 endpoint 表→ src/index.js门面与请求体构造→ src/transport/http.js 与 src/transport/playwright.js传输层→ src/normalize.js响应归一化→ src/codetables/代码表→ test/fixtures/响应样本notices-sample.json、case-found-sample.json、properties-sample.json、blocked.json等。这个技能的可复用之处不在某个 endpoint而在结构直接 HTTP 打底降依赖、浏览器分层兜底保可用、jitter 预算 熔断三重保护保 IP、fail-open 代码表防静默错误、只读与诚实声明守合规。任何无公开 API 反爬激进 强合规的政务数据查询都可以照着这套骨架搭。【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考