DB_JOB/작업파일/공공기관2/15.한국청소년활동진흥원/_oscan.py
hehihoho3 b0acd1e705 백업: 셀병합 정상화(D~J)+KDHC 옵션2/행높이17, 오늘(06-21) 제출 17곳 검수·압축
- 공공기관2/3 작업본 + 오늘 제출 17곳 D~J 카테고리 셀병합 정상화
- 한국지역난방공사 옵션2(고아셀 F98 수정)+전행 높이17
- 제출_프리랜서2_2026-06-21.zip 생성(17개 xlsx, 2,468행)

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

61 lines
2.7 KiB
Python

# -*- coding: utf-8 -*-
import openpyxl,sys,urllib.request,ssl,re,bs4,time
sys.stdout.reconfigure(encoding='utf-8')
ctx=ssl.create_default_context(); ctx.check_hostname=False; ctx.verify_mode=ssl.CERT_NONE
def fetch(u,t=3):
for i in range(t):
try: return urllib.request.urlopen(urllib.request.Request(u,headers={'User-Agent':'Mozilla/5.0'}),timeout=18,context=ctx).read()
except:
if i==t-1: raise
time.sleep(1.5)
MARK=re.compile(r'open(?:type|code)_?0*([1-4])\.(?:jpg|png|gif)',re.I)
def types_in(html, soup):
ts=set()
for m in MARK.finditer(html): ts.add(int(m.group(1)))
return ts
def is_linked(soup):
for a in soup.find_all('a'):
if 'kogl' in (a.get('href','') or '').lower() and a.find('img'): return True
return False
def detail_links(listurl, soup, html):
base=listurl.rsplit('/',1)[0]+'/'
links=set()
for a in soup.find_all('a'):
hr=a.get('href','') or ''
if re.search(r'_view\.jsp|view\.jsp|View\.jsp',hr) and ('no=' in hr or 'idx=' in hr or 'seq=' in hr):
links.add(hr if hr.startswith('http') else base+hr.lstrip('/').replace('','') if hr.startswith('/') else base+hr)
# normalize
out=[]
for l in links:
if l.startswith('http'): out.append(l)
elif l.startswith('/'): out.append('https://www.kywa.or.kr'+l)
else: out.append(base+l)
return list(dict.fromkeys(out))[:10]
wb=openpyxl.load_workbook('한국청소년활동진흥원.xlsx'); ws=wb.active
out=[]
for r in range(3,ws.max_row+1):
url=ws.cell(r,11).value; L=ws.cell(r,12).value; curO=ws.cell(r,15).value
if not url or not str(url).startswith('http') or 'kywa.or.kr' not in url or L=='사이트':
continue
try:
h=fetch(url); html=h.decode('utf-8','ignore'); soup=bs4.BeautifulSoup(h,'html.parser')
ts=types_in(html,soup); linked=is_linked(soup)
src='page'
if L=='게시판':
dls=detail_links(url,soup,html)
for d in dls:
try:
hh=fetch(d); HH=hh.decode('utf-8','ignore'); ss=bs4.BeautifulSoup(hh,'html.parser')
ts|=types_in(HH,ss); linked=linked or is_linked(ss)
except: pass
src='board(%d)'%len(dls)
newO='%s유형'%(','.join(str(x) for x in sorted(ts))) if ts else '미부착'
flag='' if newO==curO else ' <<CHANGE'
out.append('r%d B%s [%s] curO=%s -> %s Q=%s (%s)%s'%(r,ws.cell(r,2).value,L,curO,newO,'Y' if linked else 'N',src,flag))
except Exception as e:
out.append('r%d ERR %s'%(r,str(e)[:40]))
open('_oscan_out.txt','w',encoding='utf-8').write('\n'.join(out))
print('\n'.join(out))
print('DONE')