# -*- coding: utf-8 -*- import urllib.request, ssl, re, json, time from urllib.parse import quote, urlsplit, urlunsplit from concurrent.futures import ThreadPoolExecutor ctx=ssl.create_default_context(); ctx.check_hostname=False; ctx.verify_mode=ssl.CERT_NONE def enc(u): p=urlsplit(u); return urlunsplit((p.scheme,p.netloc,p.path,quote(p.query,safe='=&'),p.fragment)) def get(u): for _ in range(3): try: req=urllib.request.Request(enc(u),headers={'User-Agent':'Mozilla/5.0'}) return urllib.request.urlopen(req,context=ctx,timeout=18).read().decode('utf-8','replace') except Exception: time.sleep(0.6) return None rows={x['r']:x for x in json.load(open('_sgp_rows.json',encoding='utf-8'))} # pages+boards >=18, seogwipo internal targets=[x for x in rows.values() if x['r']>=18 and x['L'] in ('페이지','게시판') and x['url'] and 'seogwipo.go.kr' in x['url'] and '/tool/' not in x['url']] def clean(t): return re.sub(r'\s+',' ',re.sub(r'<[^>]+>','',t)).strip() def task(x): h=get(x['url']) if not h: return x['r'],{'fetch':False} # find tab-menu uls (depth1 candidates): ul with class containing tab-menu OR id=sources res=[] for m in re.finditer(r'