인프런 커뮤니티 질문&답변
1-1강의에서 거래대금이 정확하게 출력을 못하는데...방법이 없을까요?
해결된 질문
작성
·
42
·
수정됨
퀴즈
주식 데이터 필터링 시 '노이즈'를 정의하고 적용하는 데 사용되는 파일은 무엇인가요?
main.py
collector.py
model.py
config.py
답변 1
0
구체적인 프롬프트 드립니다
네이버 금융(finance.naver.com)에서 코스피/코스닥 상승 종목의 거래대금을 포함한
데이터를 스크래핑하는 Python 코드를 작성해줘.
━━━ 핵심 배경 ━━━
네이버 금융 상승 종목 페이지(https://finance.naver.com/sise/sise_rise.naver?sosok=0)는
기본 테이블에 거래대금 컬럼이 표시되지 않는다.
거래대금을 보려면 반드시 아래 2단계를 거쳐야 한다:
1단계) field_submit.naver에 POST 요청으로 표시할 컬럼을 설정
2단계) 설정된 쿠키를 가지고 sise_rise.naver를 GET 요청
━━━ 1단계: 필드 설정 (field_submit) ━━━
- URL: https://finance.naver.com/sise/field_submit.naver
- Method: POST
- Content-Type: application/x-www-form-urlencoded
- 파라미터 (form data):
menu=up
returnUrl=http://finance.naver.com/sise/sise_rise.naver?sosok={sosok}
fieldIds=quant (거래량)
fieldIds=amount (거래대금) ← 이게 핵심
fieldIds=open_val (시가)
fieldIds=market_sum (시가총액)
fieldIds=per (PER)
fieldIds=roe (ROE)
* fieldIds는 동일 키로 여러 값을 보낸다 (multipart가 아니라 repeated key).
* sosok 값: "0" = 코스피, "1" = 코스닥
* allow_redirects=False로 설정해야 쿠키만 받고 리다이렉트를 따라가지 않는다.
* 이 POST 요청의 응답 자체는 중요하지 않다.
목적은 세션 쿠키에 필드 설정을 저장하는 것이다.
━━━ 2단계: 상승 종목 페이지 스크래핑 ━━━
- URL: https://finance.naver.com/sise/sise_rise.naver?sosok={sosok}
- Method: GET (1단계와 동일한 세션으로 요청해야 쿠키가 유지됨)
- 인코딩: euc-kr (resp.encoding = "euc-kr")
- 파서: lxml (BeautifulSoup)
field_submit 후 테이블의 컬럼 순서는 다음과 같다:
N | 종목명 | 현재가 | 전일비 | 등락률 | 거래량 | 거래대금 | 시가 | 시가총액 | PER |
ROE
(인덱스: 0 1 2 3 4 5 6 7 ...)
- 테이블: <table class="type_2"> 안의 <tr> 행들
- 각 행의 <td>를 인덱스로 접근
- 종목코드: td[1] 안의 <a> 태그 href에서 code=(\d{6}) 정규식 추출
- 종목명: td[1] 안의 <a> 태그 텍스트
- 현재가(종가): td[2] 텍스트 → 쉼표 제거 후 int
- 등락률: td[4] 텍스트 → '%' 제거 후 float (예: "+29.93%" → 29.93)
- 거래량: td[5] 텍스트 → 쉼표 제거 후 int
- 거래대금: td[6] 텍스트 → 쉼표 제거 후 int (단위: 백만원)
- 시가: td[7] 텍스트 → 쉼표 제거 후 int
━━━ 주의사항 ━━━
1. requests.Session()을 사용해서 1단계와 2단계의 쿠키를 공유해야 한다.
세션 없이 별도 요청하면 거래대금 컬럼이 안 나온다.
2. User-Agent 헤더를 반드시 설정해야 한다 (브라우저 UA 문자열).
없으면 403 또는 빈 응답이 올 수 있다.
3. 거래대금 단위는 백만원이다.
예: 테이블에 "8,656"이면 실제 86억 5600만원이다.
필터에서 "50억 이상"을 체크하려면 5,000 이상인지 비교해야 한다.
4. 빈 행(구분선) 처리: <td>가 부족한 <tr>이 섞여 있으므로
len(tds) < 8 이면 skip 해야 한다.
5. 종목코드 링크가 없는 행도 있으므로 <a> 태그 존재 여부를 체크해야 한다.
6. 숫자 파싱 실패 가능성: 쉼표 제거 후에도 빈 문자열이나 '-' 같은 값이
올 수 있으므로 try/except로 감싸거나 None 반환 처리가 필요하다.
━━━ 기대 출력 형태 ━━━
각 종목을 아래 필드를 가진 dataclass로 반환해줘:
- code: str (6자리 종목코드)
- name: str (종목명)
- market: str ("KOSPI" 또는 "KOSDAQ")
- open: int (시가)
- close: int (종가/현재가)
- volume: int (거래량)
- trading_value: int (거래대금, 백만원 단위)
- change_pct: float (등락률, %)
사용 라이브러리: requests, beautifulsoup4 (lxml 파서)
---
★ Insight ─────────────────────────────────────
이 프롬프트가 구체적인 이유는 네이버 금융의 함정을 모두 명시하기 때문입니다:
- field_submit 2단계 구조를 모르면 거래대금이 안 나옴
- fieldIds repeated key 방식을 모르면 마지막 값만 전송됨
- euc-kr 인코딩을 빠뜨리면 한글이 깨짐
- 세션 쿠키 공유를 안 하면 1단계가 무의미해짐
이런 디테일 없이 "네이버에서 거래대금 크롤링해줘"라고만 하면, 대부분 기본 페이지만
긁어서 거래대금 컬럼이 없는 결과를 받게 됩니다.
─────────────────────────────────────────────────






주신 프롬프트로 잘 해결됩습니다.
감사합니다 ㅠㅠ