seawolf2357 commited on
Commit
4b3b2a0
·
verified ·
1 Parent(s): 9087bd1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +82 -40
app.py CHANGED
@@ -109,37 +109,46 @@ LOCAL_GOV_KEYWORDS = [
109
 
110
  # 지역 매칭을 위한 상세 키워드 (지역명 -> 매칭 키워드들)
111
  REGION_MATCH_KEYWORDS = {
112
- "서울": ["서울", "서울특별시", "서울시"],
113
- "부산": ["부산", "부산광역시", "부산시"],
114
- "대구": ["대구", "대구광역시", "대구시"],
115
- "인천": ["인천", "인천광역시", "인천시"],
116
- "광주": ["광주", "광주광역시", "광주시"], # 경기도 광주시와 구분 필요
117
- "대전": ["대전", "대전광역시", "대전시"],
118
- "울산": ["울산", "울산광역시", "울산시"],
119
- "세종": ["세종", "세종특별자치시", "세종시"],
120
- "경기": ["경기", "경기도", "수원", "성남", "고양", "용인", "부천", "안산", "안양",
 
 
121
  "남양주", "화성", "평택", "의정부", "시흥", "파주", "김포", "광명", "광주시",
122
  "군포", "하남", "오산", "이천", "안성", "의왕", "양평", "여주", "과천",
123
  "구리", "포천", "동두천", "가평", "연천"],
124
- "강원": ["강원", "강원도", "강원특별자치도", "춘천", "원주", "강릉", "동해", "태백",
 
125
  "속초", "삼척", "홍천", "횡성", "영월", "평창", "정선", "철원", "화천",
126
  "양구", "인제", "고성", "양양"],
127
- "충북": ["충북", "충청북도", "청주", "충주", "제천", "보은", "옥천", "영동", "증평",
 
128
  "진천", "괴산", "음성", "단양"],
129
- "충남": ["충남", "충청남도", "천안", "공주", "보령", "아산", "서산", "논산", "계룡",
 
130
  "당진", "금산", "부여", "서천", "청양", "홍성", "예산", "태안"],
131
- "전북": ["전북", "전라북도", "전북특별자치도", "전주", "군산", "익산", "정읍", "남원",
 
132
  "김제", "완주", "진안", "무주", "장수", "임실", "순창", "고창", "부안"],
133
- "전남": ["전남", "전라남도", "목포", "여수", "순천", "나주", "광양", "담양", "곡성",
 
134
  "구례", "고흥", "보성", "화순", "장흥", "강진", "해남", "영암", "무안",
135
  "함평", "영광", "장성", "완도", "진도", "신안"],
136
- "경북": ["경북", "경상북도", "포항", "경주", "김천", "안동", "구미", "영주", "영천",
 
137
  "상주", "문경", "경산", "군위", "의성", "청송", "영양", "영덕", "청도",
138
  "고령", "성주", "칠곡", "예천", "봉화", "울진", "울릉"],
139
- "경남": ["경남", "경상남도", "창원", "진주", "통영", "사천", "김해", "밀양", "거제",
 
140
  "양산", "의령", "함안", "창녕", "고성", "남해", "하동", "산청", "함양",
141
  "거창", "합천"],
142
- "제주": ["제주", "제주도", "제주특별자치도", "제주시", "서귀포"]
143
  }
144
 
145
 
@@ -160,24 +169,52 @@ def extract_region_from_text(text: str) -> Optional[str]:
160
  if kw in region_text:
161
  return region
162
 
163
- # 2. 텍스트 전체에서 지역 키워드 검색
164
- for region, keywords in REGION_MATCH_KEYWORDS.items():
 
 
 
 
165
  for kw in keywords:
166
- # 정확한 매칭을 위해 키워드가 단어 경계에 있는지 확인
167
  if kw in text:
168
  # "광주"의 경우 "경기도 광주시"와 "광주광역시" 구분 필요
169
- if kw == "광주":
170
- if "광주광역시" in text or ("광주" in text and "경기" not in text and "경기도" not in text):
171
- return "광주"
172
- elif kw == "광주시":
173
- # 경기도 광주시인 경우 경기로 처리
174
- if "경기" in text:
175
- return "경기"
176
- else:
177
- return "광주"
178
  else:
179
  return region
180
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  return None
182
 
183
 
@@ -524,14 +561,19 @@ def fetch_announcements(
524
 
525
  try:
526
  # API에서 더 많은 데이터 요청 (필터링 후 충분한 결과를 위해)
527
- # 기관유형/지역/상태 필터링이 있으면 더 많이 가져옴
528
- needs_more_data = (
529
  org_type != "전체" or
530
  region != "전체(지역)" or
531
  status_filter == "진행중"
532
  )
533
- fetch_multiplier = 5 if needs_more_data else 1 # 필터링 시 5배 더 가져옴
534
- api_fetch_count = min(500, max(100, rows * fetch_multiplier * page)) # API 최대 500건, 최소 100건
 
 
 
 
 
535
 
536
  params = {
537
  "crtfcKey": API_KEY,
@@ -602,17 +644,17 @@ def fetch_announcements(
602
  # 수행기관
603
  exec_org = item.get("excInsttNm", "") or ""
604
 
605
- # 지역 추출 (사업명 > 소관기관 > 수행기관 순으로 확인)
606
- item_region = extract_region_from_text(title)
 
 
 
 
 
607
  if not item_region:
608
  item_region = extract_region_from_text(author)
609
  if not item_region:
610
  item_region = extract_region_from_text(exec_org)
611
- # 해시태그에서도 지역 정보 확인
612
- if not item_region:
613
- hash_tags = item.get("hashTags", "")
614
- if hash_tags:
615
- item_region = extract_region_from_text(hash_tags)
616
 
617
  # 기관유형 분류
618
  item_org_type = classify_org_type(author)
 
109
 
110
  # 지역 매칭을 위한 상세 키워드 (지역명 -> 매칭 키워드들)
111
  REGION_MATCH_KEYWORDS = {
112
+ "서울": ["서울", "서울특별시", "서울시", "SBA", "서울산업진흥원", "서울경제진흥원",
113
+ "서울신용보증재단", "서울테크노파크", "서울창업허브", "SH공사"],
114
+ "부산": ["부산", "부산광역시", "부산시", "부산경제진흥원", "부산테크노파크"],
115
+ "대구": ["대구", "대구광역시", "대구시", "대구경북", "대구테크노파크"],
116
+ "인천": ["인천", "인천광역시", "인천시", "인천경제자유구역", "인천테크노파크"],
117
+ "광주": ["광주", "광주광역시", "광주시", "광주전남", "광주테크노파크"], # 경기도 광주시와 구분 필요
118
+ "대전": ["대전", "대전광역시", "대전시", "대전테크노파크", "대전경제통상진흥원"],
119
+ "울산": ["울산", "울산광역시", "울산시", "울산테크노파크", "울산경제진흥원"],
120
+ "세종": ["세종", "세종특별자치시", "세종시", "세종테크노파크"],
121
+ "경기": ["경기", "경기도", "경기TP", "경기테크노파크", "경기경제과학진흥원",
122
+ "수원", "성남", "고양", "용인", "부천", "안산", "안양",
123
  "남양주", "화성", "평택", "의정부", "시흥", "파주", "김포", "광명", "광주시",
124
  "군포", "하남", "오산", "이천", "안성", "의왕", "양평", "여주", "과천",
125
  "구리", "포천", "동두천", "가평", "연천"],
126
+ "강원": ["강원", "강원도", "강원특별자치도", "강원TP", "강원테크노파크", "강원경제진흥원",
127
+ "춘천", "원주", "강릉", "동해", "태백",
128
  "속초", "삼척", "홍천", "횡성", "영월", "평창", "정선", "철원", "화천",
129
  "양구", "인제", "고성", "양양"],
130
+ "충북": ["충북", "충청북도", "충북TP", "충북테크노파크", "충청북도기업진흥원",
131
+ "청주", "충주", "제천", "보은", "옥천", "영동", "증평",
132
  "진천", "괴산", "음성", "단양"],
133
+ "충남": ["충남", "충청남도", "충남TP", "충남테크노파크", "충남경제진흥원",
134
+ "천안", "공주", "보령", "아산", "서산", "논산", "계룡",
135
  "당진", "금산", "부여", "서천", "청양", "홍성", "예산", "태안"],
136
+ "전북": ["전북", "전라북도", "전북특별자치도", "전북TP", "전북테크노파크", "전북경제통상진흥원",
137
+ "전주", "군산", "익산", "정읍", "남원",
138
  "김제", "완주", "진안", "무주", "장수", "임실", "순창", "고창", "부안"],
139
+ "전남": ["전남", "전라남도", "전남TP", "전남테크노파크", "전남경제통상진흥원",
140
+ "목포", "여수", "순천", "나주", "광양", "담양", "곡성",
141
  "구례", "고흥", "보성", "화순", "장흥", "강진", "해남", "영암", "무안",
142
  "함평", "영광", "장성", "완도", "진도", "신안"],
143
+ "경북": ["경북", "경상북도", "경북TP", "경북테크노파크", "경북경제진흥원",
144
+ "포항", "경주", "김천", "안동", "구미", "영주", "영천",
145
  "상주", "문경", "경산", "군위", "의성", "청송", "영양", "영덕", "청도",
146
  "고령", "성주", "칠곡", "예천", "봉화", "울진", "울릉"],
147
+ "경남": ["경남", "경상남도", "경남TP", "경남테크노파크", "경남경제진흥원",
148
+ "창원", "진주", "��영", "사천", "김해", "밀양", "거제",
149
  "양산", "의령", "함안", "창녕", "고성", "남해", "하동", "산청", "함양",
150
  "거창", "합천"],
151
+ "제주": ["제주", "제주도", "제주특별자치도", "제주시", "서귀포", "제주TP", "제주테크노파크"]
152
  }
153
 
154
 
 
169
  if kw in region_text:
170
  return region
171
 
172
+ # 2. 텍스트 전체에서 지역 키워드 검색 (우선순위 있게)
173
+ # 광역시/특별시 먼저 체크 (더 구체적인 것 우선)
174
+ priority_regions = ["서울", "부산", "대구", "인천", "광주", "대전", "울산", "세종"]
175
+
176
+ for region in priority_regions:
177
+ keywords = REGION_MATCH_KEYWORDS.get(region, [])
178
  for kw in keywords:
 
179
  if kw in text:
180
  # "광주"의 경우 "경기도 광주시"와 "광주광역시" 구분 필요
181
+ if region == "광주":
182
+ if "경기" in text or "경기도" in text:
183
+ continue # 경기도 광주시이므로 스킵
184
+ return "광주"
 
 
 
 
 
185
  else:
186
  return region
187
 
188
+ # 3. 도 단위 지역 체크
189
+ province_regions = ["경기", "강원", "충북", "충남", "전북", "전남", "경북", "경남", "제주"]
190
+ for region in province_regions:
191
+ keywords = REGION_MATCH_KEYWORDS.get(region, [])
192
+ for kw in keywords:
193
+ if kw in text:
194
+ return region
195
+
196
+ return None
197
+
198
+
199
+ def extract_region_from_hashtags(hash_tags: str) -> Optional[str]:
200
+ """해시태그 문자열에서 지역 정보 추출 (쉼표로 구분된 형태)"""
201
+ if not hash_tags:
202
+ return None
203
+
204
+ # 해시태그는 "2026,금융,서울,중소벤처기업부" 형태
205
+ tags = [t.strip() for t in hash_tags.split(",")]
206
+
207
+ # 정확히 지역명과 일치하는 태그 찾기
208
+ region_names = list(REGION_MATCH_KEYWORDS.keys())
209
+
210
+ for tag in tags:
211
+ if tag in region_names:
212
+ return tag
213
+ # 약간의 변형도 체크
214
+ for region in region_names:
215
+ if region in tag or tag in REGION_MATCH_KEYWORDS.get(region, []):
216
+ return region
217
+
218
  return None
219
 
220
 
 
561
 
562
  try:
563
  # API에서 더 많은 데이터 요청 (필터링 후 충분한 결과를 위해)
564
+ # 지역+기관유형 필터링 시 API가 완벽하게 필터링하지 못하므로 최대한 많이 가져옴
565
+ needs_client_filter = (
566
  org_type != "전체" or
567
  region != "전체(지역)" or
568
  status_filter == "진행중"
569
  )
570
+
571
+ if needs_client_filter:
572
+ # 클라이언트 필터링 필요 시 항상 최대 500건 요청
573
+ api_fetch_count = 500
574
+ else:
575
+ # 필터 없을 때는 페이지에 필요한 만큼만
576
+ api_fetch_count = min(500, rows * page + 50)
577
 
578
  params = {
579
  "crtfcKey": API_KEY,
 
644
  # 수행기관
645
  exec_org = item.get("excInsttNm", "") or ""
646
 
647
+ # 지역 추출 (해시태그 > 사업명 > 소관기관 > 수행기관 순으로 확인)
648
+ # 해시태그가 가장 정확한 지역 정보를 담고 있음
649
+ hash_tags = item.get("hashTags", "")
650
+ item_region = extract_region_from_hashtags(hash_tags)
651
+
652
+ if not item_region:
653
+ item_region = extract_region_from_text(title)
654
  if not item_region:
655
  item_region = extract_region_from_text(author)
656
  if not item_region:
657
  item_region = extract_region_from_text(exec_org)
 
 
 
 
 
658
 
659
  # 기관유형 분류
660
  item_org_type = classify_org_type(author)