diff --git a/README.md b/README.md new file mode 100644 index 0000000..b1d207d --- /dev/null +++ b/README.md @@ -0,0 +1,98 @@ +# stock-news-crawler + +한국 주식 분석 플랫폼의 **뉴스 크롤링 서비스**. 네이버 금융에서 종목별 뉴스를 수집하여 Redis Streams에 발행합니다. + +## 기능 + +- **네이버 금융 뉴스 크롤링**: 종목별 관련 뉴스 기사 수집 (제목, 출처, 날짜, URL) +- **중복 제거**: URL 기반 중복 기사 자동 필터링 +- **페이지네이션**: 종목당 최대 N 페이지까지 크롤링 +- **User-Agent 로테이션**: 차단 방지를 위한 UA 순환 +- **Rate Limiting**: 초당 1건으로 요청 속도 제어 +- **비동기 워커**: Redis Streams 기반 작업 큐 소비 + +## API 엔드포인트 + +| 메서드 | 경로 | 설명 | +|--------|------|------| +| GET | `/health` | 서비스 상태 | +| GET | `/streams` | Redis Stream 큐 길이 | +| POST | `/collect/news` | 뉴스 수집 트리거 | + +### 요청 예시 + +```bash +# 뉴스 수집 (삼성전자 + SK하이닉스, 3페이지) +curl -X POST http://localhost:8003/collect/news \ + -H "Content-Type: application/json" \ + -d '{"stock_codes": ["005930", "000660"], "max_pages": 3}' +``` + +### 응답 + +```json +{"status": "queued", "message_id": "1700000000000-0", "stock_codes": ["005930", "000660"]} +``` + +## 데이터 파이프라인 + +``` +POST /collect/news + │ + ▼ + queue:trigger-news ──→ Worker (NewsCollector) + │ + ▼ + queue:raw-news + │ + ▼ + (downstream services) +``` + +## 크롤링 대상 + +| 소스 | URL 패턴 | 데이터 | +|------|---------|--------| +| 네이버 금융 | `finance.naver.com/item/news.naver?code={code}` | 종목 관련 뉴스 기사 | + +수집 데이터 필드: +- `title` - 기사 제목 +- `url` - 기사 링크 +- `source` - 출처 (언론사명) +- `published_at` - 발행 시각 +- `stock_codes` - 관련 종목 코드 +- `sentiment` - 감성 (기본 NEUTRAL, 추후 분석 가능) + +## 프로젝트 구조 + +``` +stock-news-crawler/ +├── pyproject.toml +├── Dockerfile +├── .dockerignore +└── src/stock_news_crawler/ + ├── __init__.py + ├── api.py # FastAPI 엔드포인트 + ├── crawler.py # NewsCollector (네이버 금융 크롤러) + └── worker.py # Redis Stream 소비자 + API 서버 실행 +``` + +## 환경변수 + +| 변수 | 설명 | 기본값 | +|------|------|--------| +| `REDIS_URL` | Redis 연결 URL | `redis://localhost:6379/0` | +| `LOG_LEVEL` | 로그 레벨 | `INFO` | + +## 로컬 실행 + +```bash +pip install -e ../stock-common && pip install -e . +python -m stock_news_crawler.worker +``` + +## 의존성 + +- `stock-common` - 공유 라이브러리 +- `beautifulsoup4` + `lxml` - HTML 파싱 (stock-common에 포함된 aiohttp로 HTTP 요청) +- Python >= 3.12