정부지원사업 공고 수집 데몬(gov-scraper) 추가
- government/ Node 데몬: Open API 우선 + HTML 보조 + 디스커버리 전략 - Strategy 패턴 소스 어댑터: KStartupApiSource(공공데이터 Open API), GenericHtmlSource(config 기반) - sundol 3단계 폴백 크롤러(cheerio→Jina→Playwright CDP) Node 재구현, sundol-chrome(9222) 재사용 - Oracle thick 모드(Instant Client + sso 지갑) 접속, gov_source/gov_opportunity 적재(중복제거) - K-Startup 29,017건 + 중기부(mss) 30건 적재 검증, PM2 gov-daemon 등록(60분 주기) - 기업마당(bizinfo)은 자체 crtfcKey 발급 대기 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
34
government/src/util.js
Normal file
34
government/src/util.js
Normal file
@@ -0,0 +1,34 @@
|
||||
// 공용 유틸: HTML 엔티티 디코드, YYYYMMDD 날짜 파싱.
|
||||
|
||||
const ENTITIES = {
|
||||
'&': '&', '<': '<', '>': '>', '"': '"',
|
||||
''': "'", ''': "'", ' ': ' ',
|
||||
};
|
||||
|
||||
export function decodeEntities(s) {
|
||||
if (s == null) return null;
|
||||
return String(s)
|
||||
.replace(/&|<|>|"|'|'| /g, (m) => ENTITIES[m])
|
||||
.replace(/&#(\d+);/g, (_, n) => String.fromCharCode(Number(n)))
|
||||
.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 'YYYYMMDD' 또는 'YYYY-MM-DD' 를 Date 로. 형식 불일치면 null.
|
||||
*/
|
||||
export function parseYmd(s) {
|
||||
if (s == null) return null;
|
||||
const digits = String(s).replace(/[^0-9]/g, '');
|
||||
if (digits.length !== 8) return null;
|
||||
const y = Number(digits.slice(0, 4));
|
||||
const m = Number(digits.slice(4, 6));
|
||||
const d = Number(digits.slice(6, 8));
|
||||
if (m < 1 || m > 12 || d < 1 || d > 31) return null;
|
||||
return new Date(Date.UTC(y, m - 1, d));
|
||||
}
|
||||
|
||||
export function nonEmpty(s) {
|
||||
if (s == null) return null;
|
||||
const t = String(s).trim();
|
||||
return t === '' ? null : t;
|
||||
}
|
||||
Reference in New Issue
Block a user