정부지원사업 공고 수집 데몬(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:
2026-06-10 04:36:50 +00:00
parent 5700449bfd
commit cbc5ba5663
23 changed files with 1639 additions and 0 deletions

78
government/README.md Normal file
View File

@@ -0,0 +1,78 @@
# 정부지원사업 수집 데몬 (gov-scraper)
한국 정부지원사업 공고를 주기적으로 수집해 Oracle DB(`gov_opportunity`)에 적재하는 Node.js 데몬.
## 전략
**Open API 우선 + HTML 보조 + 디스커버리 확장.** 정부지원사업 공고는 소수 허브 포털에
대부분 집계되므로, API가 있는 곳은 API로(안 깨짐), 없는 곳은 HTML로 긁고, 부족분은
디스커버리로 소스를 넓힌다.
## 아키텍처
```
src/
├── config.js 환경설정(루트 .env 로드)
├── bootstrap.js LD_LIBRARY_PATH(Instant Client) 보정 후 재실행
├── db.js Oracle thick 모드 접속(sso 지갑 재사용)
├── crawler/
│ ├── browser.js sundol-chrome(CDP 9222) 연결 — 기존 인프라 재사용
│ └── crawler.js 3단계 폴백(cheerio → Jina → Playwright) [Facade]
├── sources/ [Strategy] 소스별 어댑터
│ ├── base.js OpportunitySource 인터페이스
│ ├── kstartup.js K-Startup Open API (data.go.kr 서비스키)
│ ├── genericHtml.js config 기반 범용 HTML 게시판 스크래퍼
│ ├── htmlSources.js HTML 소스 config 목록(여기에 추가)
│ └── registry.js 가용 소스 집계(키 없는 소스 자동 제외)
├── store/ gov_source/gov_opportunity 적재(중복제거)
├── pipeline.js 목록 수집 → 적재 → 상세 본문 수집
├── daemon.js 주기 폴링 데몬(PM2)
└── cli.js 수동 실행(test-db / test-crawl / run-once)
```
- **중복 제거**: `(source_code, external_id)` 유니크 키. external_id 는 API 고유키(pbanc_sn 등)
또는 게시판 글번호.
- **상세 본문**: API 소스는 목록 단계에서 본문까지 한 번에 적재(단일 패스). HTML 소스는
목록 적재 후 detail_url 을 3단계 크롤러로 긁는 2-패스.
## DB 접속 (중요)
node-oracledb **thick 모드** + Oracle Instant Client 를 쓴다. 백엔드 JDBC 와 동일하게
자동로그인 지갑(`cwallet.sso`)을 재사용하므로 **지갑 비밀번호가 필요 없다**.
(thin 모드는 sso 를 못 읽어 지갑 비밀번호가 필요한데, 그 비밀번호는 어디에도 저장돼 있지 않음)
- Instant Client: `/home/opc/oracle-ic/instantclient_23_26` (`.env``ORACLE_IC_LIB_DIR`)
- net 설정: `government/oracle-net/` — 지갑의 `sqlnet.ora``WALLET_LOCATION`
`?/network/admin` 로 가리켜 instant client 가 sso 를 못 여는 문제를 보정한 전용 설정.
## 실행
```bash
cd government
node src/cli.js test-db # DB 접속 확인
node src/cli.js run-once kstartup # K-Startup 1회 수집
node src/cli.js run-once mss # 중기부 게시판 1회 수집
node src/cli.js run-once # 가용 소스 전체 1회
node src/cli.js test-crawl <url> # 크롤러 단독 테스트
# 데몬(PM2)
pm2 start /home/opc/sundol/ecosystem.config.cjs --only gov-daemon
pm2 logs gov-daemon
```
## 새 소스 추가
- **HTML 게시판**: `src/sources/htmlSources.js``HTML_SOURCE_CONFIGS` 에 항목 추가
(listUrl, rowSelector, externalId 정규식, detailUrl 템플릿). 코드 로직 수정 불필요.
- **API**: `src/sources/``OpportunitySource` 상속 어댑터 작성 후 `registry.js` 등록.
## 디스커버리 (소스 발굴)
데몬 자체는 웹 검색을 못 하므로, 신규 소스 발굴은 Claude(WebSearch)가 수행해
`htmlSources.js` 또는 `gov_source` 에 등록한다. 후보 목록은 `docs/sources-catalog.md` 참조.
## 미완 / TODO
- **기업마당(bizinfo)**: 자체 인증키(`crtfcKey`, bizinfo.go.kr 별도 신청) 필요.
`.env``BIZINFO_CRTFC_KEY` 발급 후 어댑터 추가 예정. (data.go.kr 키와 별개)
- 중소벤처24(smes), 지자체/부처 게시판 추가.