공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
75 lines
3.0 KiB
Python
75 lines
3.0 KiB
Python
"""Inspect e-Gov sitemap_grep structure — count amThum sections and h2 text."""
|
|
import warnings
|
|
import requests
|
|
from bs4 import BeautifulSoup
|
|
|
|
warnings.filterwarnings('ignore')
|
|
UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
|
|
H = {'User-Agent': UA}
|
|
|
|
SITES = {
|
|
'당진시': 'https://www.dangjin.go.kr/kor/sitemap_11.do',
|
|
'보령시': 'https://www.brcn.go.kr/kor/sitemap_11.do',
|
|
'서천군': 'https://www.seocheon.go.kr/kor/sitemap_11.do',
|
|
'청양군': 'https://www.cheongyang.go.kr/kor/sitemap_11.do',
|
|
'태안군': 'https://www.taean.go.kr/kor/sitemap_11.do',
|
|
'서산시(top_menu)': 'https://www.seosan.go.kr/www/index.do',
|
|
'예산군': 'https://www.yesan.go.kr/kor/sitemap.do',
|
|
'천안시': 'https://www.cheonan.go.kr/kor/sitemap.do',
|
|
'홍성군': 'https://www.hongseong.go.kr/kor/sitemap.do',
|
|
}
|
|
|
|
for name, url in SITES.items():
|
|
print(f'\n=== {name} ===')
|
|
try:
|
|
r = requests.get(url, headers=H, timeout=15, verify=False, allow_redirects=True)
|
|
r.encoding = r.apparent_encoding
|
|
except Exception as e:
|
|
print(f' ERR: {e}')
|
|
continue
|
|
soup = BeautifulSoup(r.text, 'html.parser')
|
|
# Find amThum sections (eGov sitemap_grep)
|
|
amthums = soup.select('div.amThum')
|
|
if amthums:
|
|
print(f' amThum 섹션: {len(amthums)}')
|
|
for at in amthums[:10]:
|
|
h2 = at.find('h2')
|
|
h2_text = h2.get_text(strip=True) if h2 else ''
|
|
grep = at.find('div', class_='sitemap_grep')
|
|
n_list = len(grep.find_all('ul', class_='sitemap_list')) if grep else 0
|
|
n_first = len(at.find_all('a', class_='first'))
|
|
print(f' "{h2_text}" — sitemap_list={n_list}, a.first={n_first}')
|
|
continue
|
|
# Holsung 패턴 — div.sitemap.type2.nN > dl > dt + dd
|
|
sm = soup.select_one('div.sitemap[class*=type2]')
|
|
if sm:
|
|
dls = sm.find_all('dl', recursive=False)
|
|
print(f' sitemap type2 dl: {len(dls)}')
|
|
for dl in dls[:10]:
|
|
dt = dl.find('dt')
|
|
dt_text = dt.get_text(strip=True) if dt else ''
|
|
dds = dl.find_all('dd', recursive=False)
|
|
print(f' "{dt_text}" — dd={len(dds)}')
|
|
continue
|
|
# Yesan 패턴 — ul.depth1_ul
|
|
dep1 = soup.select('ul.depth1_ul > li, ul.depth1-ul > li')
|
|
if dep1:
|
|
print(f' depth1 li: {len(dep1)}')
|
|
for li in dep1[:10]:
|
|
a = li.find(['a', 'button'], recursive=False) or li.find(['a', 'button'])
|
|
if a:
|
|
txt = a.get_text(strip=True)
|
|
print(f' "{txt}"')
|
|
continue
|
|
# Seosan top_menu pattern
|
|
tm = soup.select_one('ul.top_menu')
|
|
if tm:
|
|
deps = tm.find_all('li', class_='depth1', recursive=False)
|
|
print(f' top_menu li.depth1: {len(deps)}')
|
|
for li in deps[:10]:
|
|
a = li.find('a', class_='depth1_ti')
|
|
if a:
|
|
print(f' "{a.get_text(strip=True)}"')
|
|
continue
|
|
print(' Unknown pattern')
|