generated from ttipo/project-base
feat(backend): 장소·축제·공연·전시 데이터 기반(장소 DB·동기화·조회 API) #1
@@ -0,0 +1,103 @@
|
||||
"""축제 지역 조회 진단 — 대구 축제·행사가 90일 동안 1건만 잡힌 이유가 데이터 부족인지 조회 조건 때문인지 본다.
|
||||
|
||||
세 가지로 불러 비교한다(searchFestival2, 5~6회 호출).
|
||||
A. 지역(대구 27) + 시작일 + 종료일 ← 동기화가 쓰는 조건
|
||||
B. 지역(대구 27) + 시작일만 ← 종료일 조건의 영향
|
||||
C. 전국 + 시작일 + 종료일 ← 지역 코드가 비었거나 다르게 들어간 대구 행사가 있는지(주소로 확인)
|
||||
|
||||
키는 출력하지 않는다(public_data_check 의 call 이 가린다).
|
||||
실행(저장소 루트에서): python -I -X utf8 tools/data-check/festival_region_check.py backend/.env.development
|
||||
"""
|
||||
import collections
|
||||
import importlib.util
|
||||
import re
|
||||
import sys
|
||||
from datetime import timedelta
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _load(name):
|
||||
spec = importlib.util.spec_from_file_location(name, Path(__file__).with_name(f'{name}.py'))
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(mod)
|
||||
return mod
|
||||
|
||||
|
||||
c1 = _load('public_data_check')
|
||||
DAEGU, GYEONGBUK = '27', '47'
|
||||
LOOKAHEAD_DAYS = 90
|
||||
|
||||
|
||||
def fetch(key, label, params):
|
||||
out, page = [], 1
|
||||
while page <= 10:
|
||||
d = c1.call(key, label, f'{c1.TOUR}/searchFestival2',
|
||||
{**c1.COMMON, **params, 'numOfRows': 500, 'pageNo': page, 'arrange': 'A'})
|
||||
its = c1.items_of(d)
|
||||
out += its
|
||||
if not its or len(out) >= (c1.total_of(d) or 0):
|
||||
break
|
||||
page += 1
|
||||
return out
|
||||
|
||||
|
||||
def line(it):
|
||||
return (f"{it.get('title')} ({it.get('eventstartdate')}–{it.get('eventenddate')}) "
|
||||
f"지역코드={it.get('lDongRegnCd') or '(없음)'} 분류={it.get('lclsSystm2') or '-'} 주소={str(it.get('addr1') or '')[:24]}")
|
||||
|
||||
|
||||
def main(env_path):
|
||||
key = c1.load_key(env_path)
|
||||
today = c1.kst_now()
|
||||
start = today.strftime('%Y%m%d')
|
||||
end = (today + timedelta(days=LOOKAHEAD_DAYS)).strftime('%Y%m%d')
|
||||
print(f'# 축제 지역 조회 진단 — 기간 {start} ~ {end}\n')
|
||||
|
||||
a = fetch(key, '축제 A 대구+종료일', {'eventStartDate': start, 'eventEndDate': end, 'lDongRegnCd': DAEGU})
|
||||
b = fetch(key, '축제 B 대구', {'eventStartDate': start, 'lDongRegnCd': DAEGU})
|
||||
c = fetch(key, '축제 C 전국+종료일', {'eventStartDate': start, 'eventEndDate': end})
|
||||
|
||||
print(f'A. 대구 + 종료일 조건: {len(a)}건')
|
||||
print(f'B. 대구 (종료일 조건 없음): {len(b)}건')
|
||||
print(f'C. 전국 + 종료일 조건: {len(c)}건')
|
||||
|
||||
by_code = collections.Counter(str(it.get('lDongRegnCd') or '(없음)') for it in c)
|
||||
print('\nC 의 시·도 코드 분포(상위 10):', by_code.most_common(10))
|
||||
no_code = [it for it in c if not it.get('lDongRegnCd')]
|
||||
# '해운대구' 처럼 '대구'가 글자로만 들어간 주소를 거르려고 시·도 이름으로 시작하는지 본다
|
||||
daegu_by_addr = [it for it in c if re.match(r'\s*대구(광역시)?\s', str(it.get('addr1') or ''))]
|
||||
daegu_by_code = [it for it in c if str(it.get('lDongRegnCd')) == DAEGU]
|
||||
gb = [it for it in c if str(it.get('lDongRegnCd')) == GYEONGBUK]
|
||||
print(f'C 중 지역 코드가 빈 행사: {len(no_code)}건')
|
||||
print(f'C 중 대구 — 코드 기준 {len(daegu_by_code)}건 · 주소 기준 {len(daegu_by_addr)}건')
|
||||
print(f'C 중 경북(47): {len(gb)}건')
|
||||
|
||||
long_run = [it for it in c if it.get('eventstartdate') and it.get('eventenddate')
|
||||
and (int(str(it['eventenddate'])[:8]) - int(str(it['eventstartdate'])[:8])) > 200]
|
||||
print(f'C 중 기간이 매우 긴 행사(대략 2개월 이상): {len(long_run)}건')
|
||||
|
||||
print('\n대구로 보이는 행사(주소 또는 코드):')
|
||||
seen = set()
|
||||
for it in daegu_by_addr + daegu_by_code + [i for i in b if i not in daegu_by_code]:
|
||||
cid = it.get('contentid')
|
||||
if cid in seen:
|
||||
continue
|
||||
seen.add(cid)
|
||||
print(' -', line(it))
|
||||
if no_code:
|
||||
print('\n지역 코드가 빈 행사 예(5):')
|
||||
for it in no_code[:5]:
|
||||
print(' -', line(it))
|
||||
print('\n경북 행사 예(8):')
|
||||
for it in gb[:8]:
|
||||
print(' -', line(it))
|
||||
|
||||
print(f'\n호출 수: {c1.calls}')
|
||||
if c1.errors:
|
||||
print(f'오류 {len(c1.errors)}건:')
|
||||
for e in c1.errors[:5]:
|
||||
print(' -', e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv[1] if len(sys.argv) > 1 else 'backend/.env.development')
|
||||
Reference in New Issue
Block a user