feat(news): crawl-24x7 사이클 2 — B-2/B-3/C-1/C-2/C-3/C-5 (마이그 324-326)

- 채널 인지화: news_sources.source_channel(324, documents enum 재사용) →
  문서 생성 정체성(_doc_identity)·embed/chunk 30일 게이트(crawl=전량 색인)·
  extract 후속 override(crawl→classify, preview 스킵) 분기.
- B-2 Guardian Open Platform: API 디스패치(호스트 분기, 미지 호스트=명시 실패)
  + show-fields=bodyText 전문 어댑터. fixture live 박제 + call-shape 테스트.
- B-3 구독지: playwright-fetcher 격리 컨테이너(동시 1·요청당 브라우저·storage_state
  ro mount) + politeness 사람속도(30-60s) 브라우저 경로 + fulltext 인증 라우팅
  (내용 기반 probe 게이트·relogin_requested 소비=open-스킵보다 앞·본문 페이월 마커
  게이트) + source_health probe 컬럼(325) + 세션 박제 스크립트(맥북용).
- C-2 KOSHA: 3 API live 검증·fixture 박제(board/attach/guide) — 재해사례 daily diff
  +첨부 PDF/HWP→extract 파이프라인, GUIDE 일일 cap 점진 백필(silent cap 금지 로그).
  키는 URL 직결합(재인코딩 함정 회피). daily 06:40 KST.
- C-3 정적 코퍼스: National Board 86 + TWI job-knowledge 153 일괄 CLI(멱등·politeness
  ·crawl_raw 보존·fulltext_worker 승격 필드 규약 동일).
- C-1/C-5 시드(326): 전 URL live 검증 — UK HSE(feed-full)/안전신문/고용노동부 3종
  (rss/*.do)/OSHA/EU-OSHA(후보)/SEP/1000-Word(feed-full)/Doing Philosophy/Aeon/Psyche
  (skip-video quirk).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
hyungi
2026-06-10 15:08:18 +09:00
parent 53a30449e2
commit 1842f27d89
22 changed files with 1358 additions and 16 deletions
+59
View File
@@ -0,0 +1,59 @@
"""B-3 구독 세션 1회 수동 박제 (MacBook 등 GUI 머신에서 실행).
르몽드 = Google OAuth — 자동화 브라우저 로그인은 Google 이 차단하므로
로그인 자체는 항상 사람이 headed 브라우저에서 수행하고, 본 스크립트는
그 결과(쿠키+localStorage = storage_state JSON)만 박제한다.
사용 (MacBook):
pip install playwright && playwright install chromium
python scripts/capture_subscription_session.py --profile lemonde --url https://www.lemonde.fr
1) 떠오른 브라우저에서 직접 로그인 (Google OAuth 포함)
2) 로그인 완료 확인 후 터미널에서 Enter
3) ~/.local/share/crawl-auth/lemonde.json 저장 (600)
GPU 반영:
ssh gpu 'mkdir -p ~/.local/share/crawl-auth && chmod 700 ~/.local/share/crawl-auth'
scp ~/.local/share/crawl-auth/lemonde.json gpu:.local/share/crawl-auth/
ssh gpu 'chmod 600 ~/.local/share/crawl-auth/lemonde.json'
세션 만료 후 재로그인도 동일 절차 + source_health.relogin_requested 플래그 set
(어댑터가 다음 틱에 half-open probe 로 소비).
주의: storage_state = credential 등가물. repo 안·백업 대상 경로에 두지 말 것.
"""
import argparse
from pathlib import Path
from playwright.sync_api import sync_playwright
AUTH_DIR = Path.home() / ".local" / "share" / "crawl-auth"
def main() -> None:
parser = argparse.ArgumentParser(description="B-3 구독 세션 storage_state 박제")
parser.add_argument("--profile", required=True, help="예: lemonde")
parser.add_argument("--url", required=True, help="로그인 시작 페이지")
args = parser.parse_args()
AUTH_DIR.mkdir(parents=True, exist_ok=True)
AUTH_DIR.chmod(0o700)
out = AUTH_DIR / f"{args.profile}.json"
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=False)
context = browser.new_context(viewport={"width": 1366, "height": 900})
page = context.new_page()
page.goto(args.url)
print(f"\n브라우저에서 로그인을 완료한 뒤 이 터미널에서 Enter 를 누르세요.")
input("로그인 완료 후 Enter > ")
context.storage_state(path=str(out))
browser.close()
out.chmod(0o600)
print(f"저장: {out} (600)")
print("다음: scp 로 GPU ~/.local/share/crawl-auth/ 반영 + chmod 600")
if __name__ == "__main__":
main()