gov-scraper: 기업마당(bizinfo) Open API 소스 추가

- BizinfoApiSource: bizinfo.go.kr 자체 crtfcKey 사용, /uss/rss/bizinfoApi.do
- 페이지네이션 없음 → totCnt 파악 후 전체 일괄 요청(1,463건 검증)
- bsnsSumryCn(HTML) 본문 → stripHtml 로 태그 제거, 단일패스 적재(전건 DETAILED)
- reqstBeginEndDe "YYYY-MM-DD ~ ..." → 신청기간 파싱(706건), 텍스트형은 null
- util: stripHtml, parsePeriodRange 추가
- 데몬 4소스 가동: kstartup/bizinfo/mss/smes

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-11 06:33:27 +00:00
parent f2a8f30867
commit 82504e2261
5 changed files with 134 additions and 9 deletions

View File

@@ -57,3 +57,30 @@ export function nonEmpty(s) {
const t = String(s).trim();
return t === '' ? null : t;
}
/**
* HTML 태그 제거 후 엔티티 디코드. <br>/<p>/</div> 는 줄바꿈으로.
*/
export function stripHtml(s) {
if (s == null) return null;
const text = String(s)
.replace(/<\s*br\s*\/?>/gi, '\n')
.replace(/<\/(p|div|li|tr|h[1-6])\s*>/gi, '\n')
.replace(/<[^>]+>/g, '')
.replace(/[ \t]+\n/g, '\n')
.replace(/\n{3,}/g, '\n\n')
.trim();
return decodeEntities(text);
}
/**
* "A ~ B" 형식 기간 문자열을 {start, end} Date 로. 날짜형이 아니면 null.
*/
export function parsePeriodRange(s, sep = '~') {
if (s == null) return { start: null, end: null };
const segs = String(s).split(sep).map((x) => x.trim());
return {
start: parseFlexibleDate(segs[0]),
end: parseFlexibleDate(segs[1] || segs[0]),
};
}