"""전북 미해결 사이트 3차: 군산/남원/부안/완주/임실/순창 사이트맵 URL 확정.""" import re, sys, warnings from urllib.parse import urljoin, urlparse 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' def sess(): s = requests.Session(); s.headers.update({'User-Agent': UA}); return s def fetch(s, url, t=20): r = s.get(url, timeout=t, verify=False, allow_redirects=True) meta = re.search(rb']*charset=["\']?\s*([\w-]+)', r.content[:4096], re.I) r.encoding = meta.group(1).decode('ascii','ignore') if meta else r.apparent_encoding return r def show_container(soup, label): for sel in ['div.sitemap','div#sitemap','div.sitemap_group','div.sitemap_Warp', 'div.sitemap_wrap','ul.siteMapList','div.allmenu','div#allmenu', 'div.contents','div.allmenubox','div.total_menu','div.site_map']: els = soup.select(sel) if els: print(f' [{label}] sel={sel} x{len(els)}') S = sess() # 정읍 확정: 전체메뉴보기 menuCd r = fetch(S, 'https://www.jeongeup.go.kr/index.jeongeup?menuCd=DOM_000000106002000000') soup = BeautifulSoup(r.text, 'html.parser') print('=== 정읍 사이트맵 ===', r.url) show_container(soup, '정읍') cont = soup.select_one('div.sitemap') if cont: blocks = cont.find_all('div', recursive=False) print(' div.sitemap 직계 div:', len(blocks), [ '.'.join(b.get('class',[])) for b in blocks[:8]]) if blocks: print(blocks[0].prettify()[:800]) # 부안/임실: index 페이지에서 "사이트맵/누리집지도/전체메뉴" 텍스트 가진 a 또는 그 주변 menuCd for name, url in [('부안군','https://www.buan.go.kr/index.buan?contentsSid=1'), ('임실군','https://www.imsil.go.kr/index.imsil')]: r = fetch(S, url) soup = BeautifulSoup(r.text, 'html.parser') print(f'\n=== {name} index — 사이트맵류 a ===') for a in soup.find_all('a'): t = (a.get_text() or '').strip() if re.search(r'사이트맵|누리집지도|전체메뉴', t): print(' a:', repr(t[:25]), '| href=', a.get('href'), '| onclick=', (a.get('onclick') or '')[:80]) # 부모/형제에 menuCd 있나 par = a.find_parent() print(' parent menuCd:', re.findall(r'menuCd=DOM_\d+', str(par))[:3]) # 남원/완주: menuUid/contentUid 기반 — 사이트맵 링크 a 검색 for name, url, key in [('남원시','https://www.namwon.go.kr/index.do?menuUid=ff8080818e3beff0018e40e8f63e02d2','menuUid'), ('완주군','https://www.wanju.go.kr/index.9is','contentUid')]: r = fetch(S, url) soup = BeautifulSoup(r.text, 'html.parser') print(f'\n=== {name} index — 사이트맵/전체메뉴 a ({key}) ===') found = False for a in soup.find_all('a'): t = (a.get_text() or '').strip() href = a.get('href') or '' if re.search(r'사이트맵|누리집지도|전체메뉴|site_map|sitemap', t + href, re.I): print(' a:', repr(t[:25]), '| href=', href[:100]) found = True if not found: print(' (없음) — 모든 a href에서 sitemap 토큰 검색:') for a in soup.find_all('a', href=True): if re.search(r'sitemap|site_map', a['href'], re.I): print(' ', a['href'][:110], '|', (a.get_text() or '').strip()[:20]) # 군산: 사이트맵 페이지 추정 — /main 외 흔한 경로 시도 print('\n=== 군산 사이트맵 후보 ===') for guess in ['https://www.gunsan.go.kr/sitemap','https://www.gunsan.go.kr/kor/sitemap.do', 'https://www.gunsan.go.kr/main?menuCd=','https://www.gunsan.go.kr/sitemap.do']: try: r = fetch(S, guess, t=10) print(f' {guess} -> {r.status_code} {r.url}') except Exception as e: print(f' {guess} -> ERR {type(e).__name__}') r = fetch(S, 'https://www.gunsan.go.kr/main') soup = BeautifulSoup(r.text, 'html.parser') print(' 군산 index 사이트맵류 a:') for a in soup.find_all('a'): t = (a.get_text() or '').strip() href = a.get('href') or '' if re.search(r'사이트맵|누리집지도|전체메뉴|site_map|sitemap', t + href, re.I): print(' ', repr(t[:25]), '| href=', href[:100]) # 순창: 정적 사이트맵 페이지 탐색 print('\n=== 순창 사이트맵 후보 ===') r = fetch(S, 'https://www.sunchang.go.kr/') soup = BeautifulSoup(r.text, 'html.parser') for a in soup.find_all('a'): t = (a.get_text() or '').strip() href = a.get('href') or '' if re.search(r'사이트맵|누리집지도|전체메뉴|site_map|sitemap', t + href, re.I): print(' a:', repr(t[:25]), '| href=', href[:110])