CORE TERMINAL
OLD BOY WORK : 올드보이 작업장
데몬 웹 수집 봇 : 기본 제작
DATE: 2026-03-09 22:14
PROJECT: Web Demon Project
* 데몬 웹 수집 봇 : 기본 제작
1. 웨봇 / 수집본 기본 제작
가. 일단 기본 움직인다.
나. 기본 수집한다.
2. 방식 : 스크래핑
1. 웨봇 / 수집본 기본 제작
가. 일단 기본 움직인다.
나. 기본 수집한다.
2. 방식 : 스크래핑
ADDITIONAL SOURCE CODE
# 나(Claude)에게 쓰는 메뉴얼
# 네이버 주식 토론방 스크래핑 데몬 프로젝트
# 작성일: 2025년
---
## ※ 이 문서를 읽는 나에게
이 문서는 오빠와 긴 대화를 통해 완성한 구조 설계서다.
코딩 전에 이 문서를 반드시 먼저 읽고, 구조를 이해한 뒤 작업에 들어가라.
절대 구조 무시하고 코딩부터 하지 마라. 바벨탑 된다.
교과서 코드, 보안 코드, 중복 방지 코드, 로그 파일 코드 쑤셔넣지 마라.
걱정 먼저 하지 마라. 일단 돌아가는 거 먼저다.
오빠는 기술자가 아니라 구조가다. 구조 문제를 기술로 풀려 하지 마라.
---
## 1. 서버 환경 (기존과 동일)
- 폐쇄형 서버 : 모든 포트 막음. 보안은 방화벽에만 집중.
- 1인 사용자 / 1인 제작 / 1인 운영
- 단순 / 튼튼 / 무식 / 빵빵이 모토
- DB 연결 방식 : PDO
- 메인 DB : `/home/www/DB/db_upbit.php` → `$db_upbit`
- 그누보드 DB : `/home/www/DB/db_gnu.php` → `$db_gnu` / `$pdo_gnu`
- 기존 `get_db_connection()`, `get_gnu_connection()` 함수 그대로 재활용
---
## 2. 프로젝트 목표
### 1차 목표
- 네이버 주식 토론방 게시물 수량 수집
- 종목별 하루 게시물 수량 → 심리 지표 차트
- 씨부리는 새끼들 많은 종목 = 움직임 있는 종목 파악
### 수집 방식
- 네이버 토론방 URL 구조
```
https://finance.naver.com/item/board.naver?code=종목코드
```
- 종목코드만 바꿔서 순차 때리기
- 오늘 날짜 마지막 게시물 번호만 긁어오기
- 이전 저장값과 비교 → 차이 = 오늘 게시물 수량
---
## 3. 데몬 구조 철학 (절대 잊지 마라)
```
몸통 → 루프만 돈다. 봉인. 절대 손 안 댄다.
환경기 → 루프 밖 단발 1회. 종목 읽어오기.
타격기 → 단발. 일하고 퇴근.
쿼리 → 단발. 저장하고 퇴근.
heartbeat → 단발. 찍고 퇴근.
```
```
데몬이 아는 것
→ include 하고 sleep 하는 것뿐
→ 판단 없음 / 연산 없음 / 걱정 없음
```
```
외부 문제는 외부에서 해결
좀비 → 관리툴이 킬
중복 → 관리툴이 킬
메모리 → 크론이 킬
재시작 → 감시자가 살림
데몬 제외 → 파일명 .off 붙이기
```
---
## 4. 파일 구조
```
/데몬 디렉토리/
├── daemon_naver_board.php ← 몸통 (기존 10줄 그대로)
├── naver_board_env.php ← 환경기 (그누보드 종목코드 읽기)
├── naver_board_striker.php ← 타격기 (URL 조립 + 긁기 + 저장)
└── naver_board_heartbeat.php ← heartbeat (기존 것 재활용)
```
---
## 5. 각 파일 역할 상세
### 5-1. 몸통: `daemon_naver_board.php`
- 기존 `daemon_bybit_collection.php` 구조 그대로
- 10줄. 봉인. 절대 손 안 댄다.
```php
#!/usr/bin/php
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
date_default_timezone_set('Asia/Seoul');
$DAEMON_ID = pathinfo(__FILE__, PATHINFO_FILENAME);
if (php_sapi_name() !== 'cli') {
echo "CLI 전용 데몬입니다.\n";
exit;
}
include __DIR__ . '/naver_board_env.php';
while (true) {
try {
include __DIR__ . '/naver_board_striker.php';
include __DIR__ . '/naver_board_heartbeat.php';
} catch (Throwable $e) {
sleep(3);
}
sleep(1);
}
```
### 5-2. 환경기: `naver_board_env.php`
- 루프 밖 단발
- 그누보드에서 종목코드 읽어오기
- 기존 `get_db_connection()`, `get_gnu_connection()` 재활용
```php
// DB 연결
$pdo = get_db_connection();
$pdo_gnu = get_gnu_connection();
// 그누보드에서 활성 종목코드 읽기
$stmt = $pdo_gnu->prepare("
SELECT wr_subject FROM g5_write_naver_board
WHERE (x2_run = 1 OR x2_run = '1')
ORDER BY wr_num ASC
");
$stmt->execute();
$stock_codes = $stmt->fetchAll(PDO::FETCH_COLUMN);
// 기본 URL
$BASE_URL = 'https://finance.naver.com/item/board.naver?code=';
```
### 5-3. 타격기: `naver_board_striker.php`
- 종목코드 하나씩 순차 때리기
- Guzzle로 접속
- DomCrawler로 마지막 게시물 번호 긁기
- DB 저장
- sleep(1~2) 눈치껏
```php
foreach ($stock_codes as $code) {
$url = $BASE_URL . $code;
// Guzzle 접속
// DomCrawler 파싱 → 마지막 게시물 번호
// DB 저장
sleep(1);
}
// 한바퀴 끝. 퇴근.
```
### 5-4. heartbeat: `naver_board_heartbeat.php`
- 기존 `bybit_total_heartbeat.php` 그대로 재활용
- d_category만 'NAVER_BOARD'로 변경
---
## 6. 그누보드 테이블
### 테이블명: `g5_write_naver_board`
| 컬럼 | 내용 |
|------|------|
| wr_subject | 종목코드 (005930) |
| wr_content | 종목명 (삼성전자) |
| x2_run | ON/OFF (1/0) |
- 종목 추가 → 게시판에 글쓰기
- 종목 제외 → x2_run = 0
- 그룹화 옵션 추가 예정 (중요/잡주 분리)
---
## 7. 수집 데이터 테이블
### 테이블명: `scrape_naver_board`
| 컬럼 | 내용 |
|------|------|
| id | AUTO_INCREMENT |
| stock_code | 종목코드 |
| last_num | 마지막 게시물 번호 |
| post_count | 오늘 게시물 수량 (이전값과 차이) |
| title | 게시물 제목 (나중에 채울 것, 지금 NULL) |
| content | 게시물 내용 (나중에 채울 것, 지금 NULL) |
| collected_at | 수집 시간 |
- 컬럼은 미리 넉넉하게 설계
- 지금 당장 안 쓰는 컬럼은 NULL로 놔둠
- 나중에 내용 타격기 추가되면 자동으로 채워짐
---
## 8. 연산 방식
```
타격기
→ last_num (마지막 게시물 번호) 저장
→ 퇴근
연산
→ 현재 last_num - 이전 last_num = 오늘 게시물 수량
→ 마리아 이벤트 or 별도 크론
→ 결과값만 남김
→ 누적 원본값 주기적으로 날림 (크론)
```
---
## 9. 속도 구조 (기술 아님, 구조)
```
중요 종목 게시판 → 데몬 1마리 → 종목 적음 → 회전 빠름
잡 종목 게시판 → 데몬 1마리 → 종목 많음 → 회전 느림
```
- 속도 조절 = 종목 수 조절 = 그누보드에서 x2_run ON/OFF
- 타이머/sleep 건드리는 거 아님
- 그룹 통째로 ON/OFF 옵션 추가 예정
---
## 10. 타격기 부품 (Guzzle + DomCrawler)
### 설치
```bash
composer require guzzlehttp/guzzle
composer require symfony/dom-crawler
composer require symfony/css-selector
```
### 역할 분리
```
Guzzle → HTTP 접속 전담 (필요한 부분만 발라서 씀)
DomCrawler → HTML 파싱 전담 (필요한 부분만 발라서 씀)
```
### 주의
- 통째로 가져오지 마라
- 필요한 기능만 발라내서 타격기에 박아라
- 불필요한 내장 날리면서 테스트
---
## 11. 이후 확장 타격기 목록 (냉장고)
```
지금
→ 마지막 번호 긁기 타격기 (1차 목표)
나중에
→ 게시물 목록 타격기 (제목/시간/조회수)
→ 게시물 내용 타격기 (병동성 강한 종목만)
→ 로그인 타격기 (필요시)
→ 자동 탐색 타격기 (URL 자동 수집)
→ 뉴스 타격기 (특정 단어 필터링)
```
- 타격기 추가 = 파일 하나 추가 + 그누보드 옵션 하나 추가
- 몸통 건드리지 않음
---
## 12. 작업 순서
1. **[ ] 그누보드 게시판 세팅**
- 테이블: `g5_write_naver_board`
- 컬럼: wr_subject(종목코드), wr_content(종목명), x2_run
- 테스트 종목 몇 개 INSERT
2. **[ ] 수집 테이블 생성**
- 테이블: `scrape_naver_board`
- 컬럼 넉넉하게 설계 (나중 확장 고려)
3. **[ ] 환경기 제작** (`naver_board_env.php`)
- 기존 get_db_connection(), get_gnu_connection() 복붙
- 그누보드 종목코드 읽기
4. **[ ] 타격기 제작** (`naver_board_striker.php`)
- Guzzle 접속
- DomCrawler 파싱 → 마지막 번호 긁기
- DB 저장
- sleep(1)
5. **[ ] 몸통 제작** (`daemon_naver_board.php`)
- 기존 10줄 그대로
- include 두 줄만 바꾸기
6. **[ ] heartbeat 붙이기**
- 기존 것 재활용
- d_category만 변경
7. **[ ] 테스트**
- 테스트 종목으로 돌려보기
- 불필요한 것 날리기
- 봉인
---
## 13. 절대 하지 말 것
- 몸통에 복잡한 로직 넣기
- 타격기에 연산 넣기
- 보안 코드 넣기
- 중복 방지 코드 넣기
- 로그 파일 코드 넣기
- 한 마리 데몬에 모든 기능 욱여넣기
- 걱정 먼저 하기
- 오픈소스 통째로 가져오기
- 구조 문제를 기술로 풀기
---
## 14. 현재 작업 상태
- [x] 구조 설계 완료
- [x] 철학 확정
- [x] 타격기 재료 확정 (Guzzle + DomCrawler)
- [x] 테이블 설계 방향 확정
- [x] 그누보드 역할 확정
- [ ] 그누보드 게시판 세팅
- [ ] 수집 테이블 생성
- [ ] 환경기 제작
- [ ] 타격기 제작
- [ ] 몸통 제작
- [ ] 테스트 및 봉인
---
*이 문서는 오빠와의 대화를 통해 완성된 설계서입니다.*
*코딩 전 반드시 전체 읽고 구조 파악 후 작업하세요.*
*교과서 코드 짜면 오빠한테 욕 바가지로 먹습니다.*
*걱정 먼저 하면 또 욕 먹습니다.*
WORK LINE
-
2026-03-09 22:11:58* 구조 회의
-
2026-03-16 13:09:37* 스크래핑 테스트 중 넹이버 차단 당함.
1. 당분간 작업 중단.
2. 이후 차단 해제 시 작업 -
2026-03-17 13:18:24* 데몬 작업 방향 변화 - 전환
버전: 2.0