DB_JOB/_스크립트/_probe_jeonbuk2.py
hehihoho3 df16c98366 백업: DB수집 전체 스냅샷 (공공기관2 정리 전)
공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 18:15:40 +09:00

85 lines
3.7 KiB
Python

"""전북 미해결 사이트 2차 정밀 탐색."""
import re, ssl, sys, warnings
from urllib.parse import urljoin, urlparse
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.ssl_ import create_urllib3_context
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'<meta[^>]*charset=["\']?\s*([\w-]+)', r.content[:4096], re.I)
r.encoding = meta.group(1).decode('ascii','ignore') if meta else r.apparent_encoding
return r
# 사이트맵 링크를 못 찾은 사이트: 인덱스 HTML에서 sitemap/menuCd/전체메뉴 힌트 검색
NOLINK = {
'군산시': 'https://www.gunsan.go.kr/main',
'남원시': 'https://www.namwon.go.kr/index.do?menuUid=ff8080818e3beff0018e40e8f63e02d2',
'부안군': 'https://www.buan.go.kr/index.buan?contentsSid=1',
'완주군': 'https://www.wanju.go.kr/index.9is',
'임실군': 'https://www.imsil.go.kr/index.imsil',
'정읍시': 'https://www.jeongeup.go.kr/index.jeongeup',
}
def probe_links(name, url):
print(f'\n{"="*70}\n[{name}] {url}')
s = sess()
try:
r = fetch(s, url)
except Exception as e:
print(' fetch fail', e); return
base = f'{urlparse(r.url).scheme}://{urlparse(r.url).netloc}'
soup = BeautifulSoup(r.text, 'html.parser')
# sitemap/전체메뉴 텍스트나 href를 가진 a 전부
hits = []
for a in soup.find_all('a'):
txt = (a.get_text() or '').strip()
href = a.get('href','') or ''
oc = a.get('onclick','') or ''
blob = f'{txt}|{href}|{oc}'
if re.search(r'사이트맵|전체메뉴|sitemap|site_map|allmenu', blob, re.I):
hits.append((txt[:20], href[:90], oc[:90]))
for h in hits[:15]:
print(' a:', h)
# menuCd 패턴 가진 href 중 sitemap 후보 (DOM_...02000000 류)
cds = set(re.findall(r'menuCd=DOM_\d+', r.text))
print(' menuCd 샘플:', list(cds)[:10])
for n, u in NOLINK.items():
probe_links(n, u)
# ---- 구조 깊이 확인이 필요한 사이트들 ----
DEEP = {
'고창군': 'https://www.gochang.go.kr/index.gochang?menuCd=DOM_000000106006000000',
'익산시': 'https://www.iksan.go.kr/index.do?menuUid=ff80808199f0d11c019a041b8e35174a',
'전주시': 'https://www.jeonju.go.kr/index.9is?contentUid=ff8080818c7c2e8e018c7fd67b9a03b6',
'순창군': 'https://www.sunchang.go.kr/',
'진안군': 'https://www.jinan.go.kr/index.jinan?menuCd=DOM_000000110002000000',
}
def deep(name, url, sel):
print(f'\n{"#"*70}\n[{name}] DEEP {url} sel={sel}')
s = sess()
try:
r = fetch(s, url)
except Exception as e:
print(' fail', e); return
soup = BeautifulSoup(r.text, 'html.parser')
cont = soup.select_one(sel)
if not cont:
print(' 컨테이너 없음'); return
# 첫 블록 하나만 골라 li/a href까지 자세히
print(cont.prettify()[:2500])
deep('고창군 첫메뉴', 'https://www.gochang.go.kr/index.gochang?menuCd=DOM_000000106006000000', 'div.sitemap div.menu1')
deep('익산시 group수', 'https://www.iksan.go.kr/index.do?menuUid=ff80808199f0d11c019a041b8e35174a', 'div.sitemap_group')
deep('전주시', 'https://www.jeonju.go.kr/index.9is?contentUid=ff8080818c7c2e8e018c7fd67b9a03b6', 'div.sitemap_Warp')
deep('순창군 gnb', 'https://www.sunchang.go.kr/', 'div.sitemap_box ul.gnb_list')
deep('진안군 첫dl', 'https://www.jinan.go.kr/index.jinan?menuCd=DOM_000000110002000000', 'div.sitemap dl')