📅 Sense Stock 개발 일지 (2025-06-27)
n8n 기반 뉴스 요약 자동화 시스템 Sense Stock 구축 중 진행한 작업들을 정리합니다.
오늘은 주식 시장 데이터 자동 수집을 위해 Playwright 기반 크롤링 서버를 Docker로 구성했습니다.
❓ 지난번 고민: 응답 신뢰성 부족
현재 GPT는 성향 분석 → 시장 요약 → 시나리오 제안의 형태로 응답을 출력하지만,
가장 큰 문제는 “정확한 데이터를 기반으로 하고 있는지 확인할 수 없다”는 점이었다.
예를 들어, 프롬프트에
“당일 날짜는 2025-06-26이며, 해당 날짜 기준으로 분석해줘”
라고 명시했음에도 불구하고, GPT가 “오늘 미국 증시는 하락세입니다”라고 응답했을 때,
실제로는 상승장이었다면 이건 단순 포맷 문제가 아니라 신뢰성 붕괴다.
<핵심 문제>
- GPT가 당일 날짜 기준 데이터를 진짜로 참고하고 있는지 불분명
- hallucination(추측성 서술) 가능성 존재
- 응답 형식이 들쭉날쭉해 가독성도 떨어짐
🧱 Workflow 구조
그래서 다음과 같은 Workflow를 추가 하고자한다.
Workflow
Step 1. MARKET_DATA 기반 응답 강제
- 매일 크롤링한 시장 데이터(S&P500, Nasdaq, 글로벌 지수, 주요 이슈)를 MARKET_DATA라는 이름으로 저장
- 프롬프트에서 GPT에 명확히 선언:
아래 MARKET_DATA만 기반으로 시장 상황을 판단하라.
외부 정보나 일반 상식을 사용하지 말고, 숫자 기반 흐름 및 요약 내용만 참조하여 판단하라.
Step 2. GPT 응답의 표현 → 실제 데이터 대조
- GPT가 “하락세”라고 응답했다면
→ MARKET_DATA에서 S&P500, Nasdaq, Dow 등 실제 지표가 하락했는지 비교 - 차후엔 이 판단을 자동화하는 간단한 체크 스크립트도 만들 계획
Step 3. 응답 양식 표준화 (Markdown 기반)
- 기존엔 문단 스타일이 들쭉날쭉했음
→ Markdown 포맷을 도입해 가독성과 구조화 개선
## 🧠 투자자 성향 분석 결과
## 📊 오늘의 시장 요약 (2025-06-27 기준)
- S&P500: 상승 (+0.84%)
- Nasdaq: 혼조세 (-0.12%)
- 주요 이슈: FOMC 금리 동결, Nvidia 실적 발표
## 🎯 추천 시나리오
1. (보수적) …
2. (공격적) …
3. (분석형) …
Data를 어떻게 가져올것이냐?
미국 주식 시장의 주요 지표(S&P500 Heatmap 등)를 하루 1회 자동 수집
→ 사용자 질문에 실시간 시장 맥락 정보를 포함한 응답을 생성
🗂️ 수집 방식 비교 및 시행착오
방법 | 장단점 | 최종 평가 |
Finnhub API | - 무료 60회 호출 - ETF만 가능 (지수는 불가) |
❌ Pass (제한적 + 유료 플랜 필요) |
Firecrawl MCP | - HTML 기반 크롤링 - include tag 등 옵션 - 유료 사용 |
❌ 데이터 정밀 추출 어려움 |
Puppeteer MCP | - MCP 존재만 확인 - 실사용 경험 없음 |
❓ 미확인 |
Playwright (Python) | - 브라우저 자동화 - 원하는 데이터 정확히 추출 가능 - 복잡한 구조 대응 용이 |
✅ 최종 선택 |
finviz 사이트 | - S&P500 및 글로벌 선물 지수 표 형태 제공 - 한눈에 시장 분위기 파악 가능 |
✅ 시각적으로도 우수 |
결국 finviz에서 S&P500 Heatmap을 가져오는 방식으로 확정했다.
→ 구조화된 테이블 형태로 글로벌 지수를 한눈에 볼 수 있는 페이지라, 현재 시장의 분위기를 요약하는 데 최적이라고 판단.
S&P 500 Map
× Ever heard of Finviz*Elite? Our premium service offers you real-time quotes, advanced visualizations, technical studies, and much more. Become Elite and make informed financial decisions. Find out more --> Upgrade your FINVIZ experience Join thousands o
finviz.com
Issue
기존에는 n8n 내부에서 Python 노드를 활용해 Playwright로 직접 데이터 수집을 시도했지만, 문제 발생:
- n8n Docker 이미지에는 Python도, Playwright 브라우저도 포함되어 있지 않음
- Execute Command나 Python Function 노드에서도 playwright 실행 불가
그래서 대안으로 선택한 방식은?
n8n 외부에서 Python + Playwright 크롤링 서버를 별도 운영
→ 필요할 때 n8n에서 해당 서버를 호출하거나
→ Execute Command로 해당 Python 스크립트를 컨테이너 외부에서 실행
Python Code
import asyncio
from playwright.async_api import async_playwright, TimeoutError as PlaywrightTimeout
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=False)
context = await browser.new_context()
page = await context.new_page()
await page.goto("https://finviz.com/map.ashx", wait_until="domcontentloaded", timeout=60000)
print("📌 페이지 로드 완료")
# Share map 버튼 클릭
await page.get_by_text("Share map").click()
print("🖱️ Share map 버튼 클릭됨")
# textarea 등장 기다리기
try:
await page.wait_for_selector('textarea[data-testid="copy-to-clipboard-textarea"]', timeout=10000)
print("✅ textarea 등장 완료")
except PlaywrightTimeout:
print("❌ textarea가 10초 안에 등장하지 않았습니다.")
await browser.close()
return
# 주소 추출
image_url = await page.locator('textarea[data-testid="copy-to-clipboard-textarea"]').text_content()
print("✅ 공유 URL:", image_url or "없음")
await browser.close()
asyncio.run(main())
🥊 Selenium VS Playwright
항목 | Selenium | Playwright |
🔨 출시 시점 | 오래된 기술 (2004년) | 최신 기술 (2020년, MS에서 개발) |
⚙️ 설치/환경 구성 | WebDriver 필요 (브라우저별 설치) | 브라우저 포함 설치 (npx playwright install) |
🧠 자동 대기 (auto-wait) | ❌ 명시적으로 wait 코드 필요 | ✅ 엘리먼트가 보일 때까지 자동 대기 |
🌐 멀티 브라우저 지원 | Chrome, Firefox, Edge, Safari (WebDriver로 제어) | ✅ Chromium, Firefox, WebKit (Safari까지 직접 내장) |
📱 모바일 시뮬레이션 | 일부 가능 (device emulation 복잡) | ✅ 손쉽게 가능 (iPhone, Pixel 등 프리셋 제공) |
🔄 탭/팝업/다중 페이지 | O (지원은 되지만 복잡함) | ✅ 매우 직관적 (멀티탭, 다중 페이지 간 동시 제어) |
🎯 테스트 전용 기능 | ✅ 다양한 생태계 (Selenium Grid, TestNG 등) | ✅ 자체 Playwright Test 포함 |
🔍 속도 및 안정성 | 상대적으로 느림, flaky한 경우 있음 | ✅ 빠르고 안정적 |
📸 스크린샷/비디오 기록 | 수동 구현 필요 | ✅ 내장 기능 (스크린샷, 전체 흐름 비디오 저장 가능) |
📥 파일 다운로드/업로드 처리 | 약간 번거로움 | ✅ 전용 API 있음 (page.on('download')) |
🧩 언어 지원 | Java, Python, C#, JS 등 다양 | JS/TS, Python, Java, C# 지원 (최근 확장됨) |
🧪 테스트 프레임워크 통합 | ✅ JUnit, TestNG, Pytest 등 | ✅ Playwright Test 내장 + 외부 프레임워크 연동 가능 |
하지만 내가 원한 건,
“Playwright를 쓸 수 있는 환경에서 n8n을 돌리는 것”
기존 n8n Container로 실행하는 것이 아니라 Playwright 환경을 포함한 커스텀 Docker 이미지를 만들어야한다.
Docker Rebuilding
- Dockerfile에서 playwright 설치
- docker-compose.yml로 n8n 실행 정의
- 기존 n8n 컨테이너는 폐기하되,
- 기존 설정은 그대로 유지 (볼륨 마운트 유지)
- 기존 n8n 컨테이너는 폐기하되,
- docker-compose build && up -d
- n8n Execute Command 노드에서 직접 실행
## Execute Command 노드
python3 /app/daily_scraper.py
이렇게 하면, n8n 내부에서 외부 MCP 호출 없이 바로 Playwright로 사이트 접근 → 데이터 저장까지 가능해진다.
아직 완전히 검증된 건 아니다.
Docker를 잘 모르니까, 내가 이걸 맞게 하고 있는지도 확신이 안 선다.
하지만 기존처럼 외부 MCP 서버를 돌리는 구조보다 훨씬 단순하고, 관리도 쉬워질 거라는 기대는 있다.
이렇게 시장 지표 데이터를 매일 새벽 한 번씩만 가져오고
그걸 기반으로 GPT가 사용자 질문에 응답하게 하면
불필요한 뉴스 요약이나 검색 없이, 훨씬 안정적인 정보 제공이 가능하다는 점이다.
❓ 다음 단계에서 고민 중인 것들
- Docker Image 재구성이 최우선
- MARKET_DATA를 어떻게 벡터화해서 GPT가 RAG 기반으로도 정확히 인식하게 할까?
- GPT 응답과 수집 데이터 간의 불일치 자동 감지 시스템을 어떻게 만들 수 있을까?
- 투자자 성향별 시나리오 생성에 더 많은 실시간 요소(예: 변동성, 공포/탐욕 지수 등)를 반영할 수 있을까?
'Automation Tool > n8n Project' 카테고리의 다른 글
Sense Stock, D+14 (0) | 2025.07.01 |
---|---|
Sense Stock, D+13 (0) | 2025.06.30 |
Sense Stock, D+11 (1) | 2025.06.26 |
Sense Stock, D+10 (0) | 2025.06.24 |
Sense Stock, D+9 (2) | 2025.06.23 |
댓글