gov-scraper: 신청 체크리스트 서울 거주 지역필터 적용

- generate_checklist.js: 서울 거주 기준 타 지역 한정 공고 제외(접두/주관기관 + 안전한 도·권역은 제목 본문까지)
- apply-checklist.md: 252→137건(타지역 115건 제외), 서울+전국 공고만 유지

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-11 07:52:33 +00:00
parent afff7a4703
commit ad8d200474
2 changed files with 44 additions and 122 deletions

View File

@@ -23,6 +23,38 @@ function region(title) {
const m = /^\[([^\]]{1,8})\]/.exec(title);
return m ? `\`${m[1]}\` ` : '';
}
// 거주지(서울) 기준 지원 가능 판정.
// 타 지역(광역시/도/주요 시) 키워드가 제목 접두 또는 주관기관에 있으면 제거.
// '서울'이 명시돼 있으면 유지. 둘 다 없으면 전국 사업으로 보고 유지.
// 제목 접두 + 주관기관 에서 검사하는 전체 타지역 키워드(축약어 '대전'·'광주' 등 오탐 위험 토큰 포함 가능)
const NON_SEOUL = [
'부산', '대구', '인천', '광주', '대전', '울산', '세종',
'경기', '강원', '충북', '충남', '전북', '전남', '경북', '경남', '제주',
'충청', '전라', '경상', '호남', '영남',
'수원', '성남', '용인', '화성', '부천', '안양', '안산', '시흥', '군포', '고양',
'김포', '평택', '파주', '의정부', '남양주', '청주', '충주', '제천', '천안', '아산',
'전주', '군산', '익산', '여수', '순천', '광양', '목포', '나주', '포항', '경주',
'구미', '칠곡', '문경', '안동', '창원', '김해', '진주', '양산', '밀양', '거제',
'춘천', '원주', '강릉', '홍천', '속초', '강화', '서귀포',
];
// 제목 본문까지 검사해도 안전한(흔한 단어에 잘 안 섞이는) 도/권역 키워드.
// 제외: 대전(대전환), 광주(관광주간), 경기(경기침체), 경상(경상비), 세종(세종대왕) 등 오탐 위험.
const NON_SEOUL_BODY = [
'부산', '대구', '인천', '울산', '강원', '충북', '충남', '전북', '전남',
'경북', '경남', '제주', '호남', '영남', '홍천', '청주', '천안', '전주',
'여수', '순천', '포항', '창원', '김해', '춘천', '원주', '강릉',
];
function applicableInSeoul(x) {
const prefix = (/^\[([^\]]{1,8})\]/.exec(x.TITLE) || [])[1] || '';
const strong = `${prefix} ${x.AGENCY || ''}`; // 접두 + 주관기관
const full = `${x.TITLE} ${x.AGENCY || ''}`;
if (full.includes('서울')) return true; // 서울 명시(서울·경기 등 포함) → 유지
if (NON_SEOUL.some((t) => strong.includes(t))) return false; // 접두/주관기관에 타지역 → 제거
if (NON_SEOUL_BODY.some((t) => x.TITLE.includes(t))) return false; // 제목 본문 도/권역 → 제거
return true; // 지역 신호 없음 → 전국 사업으로 유지
}
function ymd(d) {
return d ? new Date(d).toISOString().slice(0, 10) : '';
}
@@ -34,7 +66,7 @@ function line(x) {
return `- [ ] **${dtag}** (${deadline}) ${region(x.TITLE)}${cat}[${title}](${x.DETAIL_URL}) — ${x.AGENCY || ''}`;
}
const rows = await withConnection(async (conn) => {
const allRows = await withConnection(async (conn) => {
const r = await conn.execute(
SQL,
{ k1: '예비창업', k2: '예비 창업' },
@@ -44,6 +76,11 @@ const rows = await withConnection(async (conn) => {
});
await closePool();
// 서울 거주 기준: 타 지역 한정 공고 제외
const rows = allRows.filter(applicableInSeoul);
const removed = allRows.length - rows.length;
console.log(`지역 필터(서울 거주): 전체 ${allRows.length}건 → 유지 ${rows.length}건, 제거(타지역) ${removed}`);
const buckets = {
'🔴 이번 주 마감 (D-0 ~ D-7)': (d) => d <= 7,
'🟡 2주 내 (D-8 ~ D-14)': (d) => d >= 8 && d <= 14,
@@ -55,7 +92,7 @@ const today = new Date().toISOString().slice(0, 10);
const out = [];
out.push('# 정부지원사업 신청 체크리스트');
out.push('');
out.push(`> 생성일: ${today} · 대상: **예비창업자 자격 + 현재 신청 가능** 공고 (총 ${rows.length}건)`);
out.push(`> 생성일: ${today} · 대상: **예비창업자 자격 + 현재 신청 가능 + 서울 거주 지원 가능**(타 지역 한정 제외) 공고 (총 ${rows.length}건)`);
out.push('> 신청을 마치면 `[ ]` → `[x]` 로 체크하세요. 갱신: `LD_LIBRARY_PATH=$ORACLE_IC_LIB_DIR node scripts/generate_checklist.js`');
out.push('> ⚠️ 마감 "시각"과 정확한 자격요건은 각 공고 원문에서 반드시 확인하세요.');
out.push('');