尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

k-skill 的 s2b-notice-search:S2B 学校市场公告查询的零依赖 CommonJS 工具包解析

k-skill 的 s2b-notice-search:S2B 学校市场公告查询的零依赖 CommonJS 工具包解析 k-skill 的 s2b-notice-searchS2B 学校市场公告查询的零依赖 CommonJS 工具包解析【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill本文以 k-skill 仓库中packages/s2b-notice-search包的 README 为骨架深入讲解如何为韩国 S2B 학교장터www.s2b.kr公开客户公告/报价请求页面构建只读查询方案。读完本文你将掌握搜索选项规范化、tcmo001FormPOST 表单构造、列表/详情 HTML 解析以及「浏览器优先、直接 HTTP 兜底」的自动化执行策略并能直接复用该包提供的五个核心导出函数。一、包定位依赖为零的只读公告查询配方s2b-notice-search是一个dependency-free零运行时依赖的 CommonJS 工具包其职责在 README 中定义得非常清晰It normalizes search options, builds a browser/direct-HTTP recipe using S2Bs observedtcmo001Formfield names forhttps://www.s2b.kr/S2BNCustomer/tcmo001.do, parses fixture HTML for list/detail pages, and emits browser automation instructions.翻译成要点即规范化搜索选项 → 用观察到的tcmo001Form字段名构造浏览器/直接 HTTP 请求配方 → 解析列表/详情页的 fixture HTML → 输出浏览器自动化指令。整个包是只读的不执行登录、投标、报价提交、结算等写操作。从 package.json 可以看到其工程约束包名s2b-notice-search版本 0.2.1main指向src/index.jsengines.node 18并配有lintnode --check与testnode --test两个脚本。发布时仅打包src与README.md。在仓库中该包对应的技能skill定义位于 s2b-notice-search/SKILL.md其 skill.json 声明了procurement采购分类、ko-KR语言环境并挂载了vault、browser、legal三个 profile——这决定了它走浏览器优先 合法合规的执行路径。二、核心 API 总览README 给出了包的典型用法const { buildSearchRequest, normalizeSearchOptions, parseListHtml } require(s2b-notice-search) const options normalizeSearchOptions({ keyword: 냉장고, // 搜索关键词如“冰箱” dateStart: 2026-06-01, dateEnd: 2026-06-30, itemType: 물품, // 品目물품(物品)/공사(工程)/용역(劳务) privateContract: 1인 // 私下合同1인/2인 }) const request buildSearchRequest(options) const rows parseListHtml(table.../table)从 src/index.js 的导出可见完整 API 共有六个导出项导出作用normalizeSearchOptions(input)规范化搜索选项别名映射、日期校验、范围校验buildSearchRequest(input)构造tcmo001Form的 POST 请求配方含 URL、headers、bodyparseListHtml(html)解析公告列表 HTML返回公告元数据数组parseDetailHtml(html)解析详情 HTML返回标题、编号、机构、附件等结构化字段buildBrowserAutomationInstructions(input)输出浏览器自动化指令三级 fallback 通道常量BASE_URL/FORM_NAME/SEARCH_PATH分别对应https://www.s2b.kr、tcmo001Form、/S2BNCustomer/tcmo001.do其中parseListHtml与parseDetailHtml实际由 src/html.js 中的底层解析函数parseListRow、tableFields、parseAttachments、normalizeLooseDate、parseAction等支撑。三、normalizeSearchOptions搜索选项规范化与别名映射normalizeSearchOptions的输入结构在 instruction.md 的 Inputs 表格中有完整说明各字段取值如下输入字段取值/约束keyword搜索关键词如物品名organization机构/学校名称dateStart,dateEndYYYYMMDD或YYYY-MM-DD日期跨度不得超过 3 个自然月itemType물품、공사、용역、allprivateContract1인、2인、allregion地区名page≥1 的整数从 src/index.js 源码可以看到规范化在内部通过多组Map完成「人类输入 → 表单编码」的映射品目映射ITEM_TYPESall/전체→all물품/goods/1→1공사/works/2→2용역/service/services/3→3。即同时接受韩文、英文、数字三种写法。私下合同映射PRIVATE_CONTRACTS1인/one/single/1→12인/two/2→2all/전체→all。关键词字段映射KEYWORD_FIELDStitle/name/공고명/견적요청/공고명→1按标题搜索number/code/공고번호/견적요청/공고번호→2按公告编号搜索。未显式指定时默认取第一个映射值即标题字段1。日期字段映射DATE_FIELDSposted/notice/공고일→1公告日deadline/마감일/견적서제출마감일→2截止日。默认值为deadline截止日。除别名映射外规范化还承担三重校验日期格式校验normalizeDate只接受YYYYMMDD或YYYY-MM-DD且会通过Date.UTC构造后回读年月日来杜绝2026-02-31这类不存在的日历日期见测试rejects invalid dates。日期范围校验assertDateRange要求dateEnd dateStart并强制搜索跨度不超过 3 个自然月超出即抛RangeError。分页与枚举校验page必须是 ≥1 的整数枚举值不合法时通过normalizeChoice抛出unsupported ${name}错误。这些约束在 test/index.test.js 中有完整覆盖——例如dateStart: 2026-01-01, dateEnd: 2026-04-02会命中「3 calendar months」错误。四、buildSearchRequest构造 tcmo001Form 的 POST 配方buildSearchRequest是包的「请求配方」核心。它以normalizeSearchOptions的产物为基础按 instruction.md 中观察到的字段名组装表单body.set(forwardName, list01) body.set(pageNo, String(options.page)) body.set(estimateCode, ) body.set(tender_step_code, ) body.set(page_flag, ) body.set(process_yn, Y) body.set(search_yn, Y) body.set(tender_sep1, options.keywordField) // 关键词搜索字段1标题, 2编号 // tender_name: 关键词 // company_name_s: 机构名 body.set(tender_sep2, options.dateField) // 日期字段1公告日, 2截止日 // tender_date_start / tender_date_end: 起止日期YYYYMMDD // tender_item: 品目all 时置空 // estimate_kind: 私下合同all 时置空 // areaKind: 地区最终返回的request对象结构如下{ method: POST, formName: tcmo001Form, baseUrl: https://www.s2b.kr, path: /S2BNCustomer/tcmo001.do, url: https://www.s2b.kr/S2BNCustomer/tcmo001.do, headers: { content-type: application/x-www-form-urlencoded; charsetUTF-8, referer: https://www.s2b.kr/S2BNCustomer/tcmo001.do }, body, // URLSearchParams options // 规范化后的搜索选项 }其中referer被刻意设置为与目标 URL 相同这一点对通过 S2B 的会话/表单状态检查至关重要。tender_item与estimate_kind在值为all不限制时会被清空tender_name、company_name_s、tender_date_start、tender_date_end、areaKind仅在非空时才写入 body见setParam辅助函数。测试normalizes supported S2B search options and builds POST recipe对该配方逐字段断言例如输入itemType: 물품后body.get(tender_item) 1输入privateContract: 1인后body.get(estimate_kind) 1输入韩文机构名가람초后body.get(company_name_s) 가람초日期被规范化为20260601格式。五、parseListHtml列表页解析与跨行合并parseListHtml接收列表页 HTML 字符串输出结构化公告数组。从 src/index.js 与 src/html.js 的实现看其解析策略有三层按tr切分对每一行调用parseListRow提取元数据若单独一行无法成记录则将当前行与下一行拼接后重试——这是为兼容 S2B 真实页面「标题行 元数据行」跨行布局fixturetwoRowListFixture中一个公告跨两个trrowspan/colspan混排。识别详情动作解析a标签的onclick或javascript:形式的href提取 JS 函数名与参数。只有函数名匹配f_detail/fn_detail/goView的行才被当作公告行从而自动忽略顶部导航表如fncGoMenu(tgru)这类菜单跳转。形状校验hasNoticeRowShape必须同时具备 action、标题、至少一个日期且品目/机构/状态三者之一非空否则丢弃。单行记录输出字段包括{ noticeCode, // 公告编号取自 detailAction 首参或正则 ([A-Z]{2,}-\d{4}-\d{3,}) estimateCode, // 报价编号与 noticeCode 同源 title, // 公告标题a 内文本 organization, // 机构名匹配 학교|교육청|기관|초등|중학교|고등 等特征词 status, // 状态진행|마감|완료|공고|취소|유찰 itemType, // 品目물품|공사|용역 postedDate, // 公告日yyyy-mm-dd 或带时间 deadline, // 截止日 detailAction: { functionName, args, raw } // 详情跳转动作元数据 }normalizeLooseDate对日期做了「宽松化」处理支持2026-06-01、2026.06.03等多种分隔符并可附带HH:MM时间。测试中listFixture与twoRowListFixture分别验证了单行与跨行两种布局的解析正确性。六、parseDetailHtml详情页字段表与附件解析当拿到某条公告的详情页 HTML 后parseDetailHtml将其解析为完整元数据。其实现要点src/index.js字段表提取tableFields遍历所有tr按「th标签名 →td值」的成对规律生成键值映射并支持「공고번호/견적번호/견적공고번호」「기관명/수요기관」「게시일/공고일」「견적마감일/마감일/입찰마감일」等多组同义标签回退。标题回退链优先取h1–h6标题其次回退到字段表的공고명或제목。正文提取优先匹配id为content/contents/detailContent的div取不到则退回整页cleanText。附件解析parseAttachments遍历所有a解析其onclick中的下载动作如downloadFile(A001,spec.pdf)产出{ filename, action }列表。详情对象字段为title、noticeCode、estimateCode、organization、status、itemType、privateContract、postedDate、deadline、contentText、fields原始键值表、attachments。测试parses detail fixture HTML into fields, content, and attachments对该结构做了逐字段断言包括从downloadFile(A001,spec.pdf)中解析出文件名spec.pdf与动作参数。七、浏览器自动化指令浏览器优先直连兜底README 明确指出执行策略Use browser automation first because S2B may depend on session/form state. Direct HTTP is only a best-effort fallback when the same session and form tokens work.buildBrowserAutomationInstructions输出的steps数组定义了三级 fallback 通道与 instruction.md 的 Fallback order 一一对应顺序channel动作要点1aside-browser打开https://www.s2b.kr/S2BNCustomer/tcmo001.dosnapshot 页面填写可见搜索表单并提交再 snapshot 结果表与详情页动作2browseros-cdp-or-local-browser优先复用用户已启动的 BrowserOS 会话经 k-skill-browser-runtime 走 CDP否则使用本地自有浏览器以等价 POST 表单提交并解析渲染后的结果表3direct-http-best-effort仅当相同的会话 cookie、referer 与表单 token 在无浏览器环境下同样可用时才直接发送编码后的 POST body遇到登录墙、CAPTCHA、拦截、空结果或畸形响应一律视为明确失败测试documents browser automation fallback order before direct HTTP对通道顺序做了硬性断言[aside-browser, browseros-cdp-or-local-browser, direct-http-best-effort]。八、失败模式与完成标准instruction.md 归纳了四类失败模式可作为接入方的异常分类依据malformed curl/client error表单体、cookie、referer、编码或客户端超时配置错误导致 S2B 未返回正常 HTMLlogin / CAPTCHA / blocked遇到登录墙、验证码、拦截/维护/安全页时不尝试绕过直接判定失败empty可能是搜索条件确实无结果也可能是 session/form state 不匹配导致返回空列表需结合上下文区分upstream markup changeS2B 的表格结构、详情动作、隐藏输入或 JS 函数名变更时解析结果可能部分缺失或为空——这也是包以 fixture HTML 驱动测试、便于随上游变化更新的原因。一个查询任务「完成」的判定标准Done when为已在 Aside 或 fallback 浏览器中打开公开 S2B 查询表面搜索区间有效且不超过 3 个自然月列表/详情解析器已提取所需字段结果仅作只读查询使用绝不自动提交、签约或登录。九、安全与合规边界该技能在 SKILL.md 中声明了三条不可逾越的硬性规则与包只读设计一脉相承未经用户即时明确同意绝不执行支付、消息/邮件发送、最终提交、取消或公开张贴绝不在聊天、文件或 shell 参数中索取、打印或存储明文凭据绝不绕过法律、实地到场、CAPTCHA、身份核验或电子签名等边界。也就是说本包与技能只覆盖「公开公告/报价请求的只读查询」这一合法表面投标参与、报价提交、登录、支付、中标/合同处理等一律不在能力范围内。十、在仓库中运行验证该包位于 packages/s2b-notice-search可在仓库根目录执行npm test --prefix packages/s2b-notice-search # node --test 运行全部测试 npm run lint --prefix packages/s2b-notice-search # node --check 语法检查 src 与 testNode.js 18 为必需环境见engines字段。CHANGELOG.md 记录了其演进0.2.0 引入 S2B 查询配方、解析器、技能与文档0.2.1 迁移共享浏览器运行时将 Aside Browser 置于 Chrome CDP 之前并修复了线上 yebigun、S2B、D2B 流程。如需在 k-skill CLI 环境中使用完整技能说明可按 SKILL.md 所述执行npx -y nomadamas/k-skill0 instruct s2b-notice-search。综上所述s2b-notice-search是一个聚焦单一业务面、零依赖、可独立测试的只读公告查询工具包规范化输入、构造tcmo001FormPOST 配方、解析列表与详情 fixture、输出三级浏览器自动化通道。其设计理念——「浏览器优先、直连兜底、合法只读」——既保证了在 S2B 依赖会话/表单状态前提下的可用性也守住了自动化执行的合规边界。【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表