🗄️ 데이터센터
home
주식거래 데이터
home

전 종목 주가데이터 저장

상장법인목록

본 페이지에서는 모든 종목데이터를 저장할 예정입니다. 이를 위해서는 전체 종목 목록이 필요한데, 이전에 스크래핑 기술 페이지에서 상장법인목록 데이터를 이미 수집해 두었던것을 활용하겠습니다.

상장법인목록 코드스니펫

import requests import pandas as pd def getCorpList(): url = 'https://kind.krx.co.kr/corpgeneral/corpList.do' data = { 'method': 'download', 'orderMode': '1', 'orderStat': 'D', 'searchType': '13', 'fiscalYearEnd': 'all', 'location': 'all', } r = requests.post(url, data=data) df = pd.read_html(r.content, header=0) df = df[0] # 리스트 내부 요소 추출 return df getCorpList()
Python
복사

상장법인목록 출력

상장법인목록 함수를 corpList 변수에 담아 출력했습니다. 회사명종목코드가 표시된 것을 확인할 수 있습니다. 이 데이터를 앞으로 활용할 예정인데, 한 가지 특이한 점이 있습니다. 종목코드가 6자리가 아닙니다. 이는 종목코드가 숫자로 처리되면서 삼성전자의 종목코드 '005930'이 '5930'으로 앞의 '00'이 제거되어 나타난 현상입니다.

상장법인목록 함수 개선

위의 종목코드 문제를 해결하기 위해 getCorpList() 함수를 개선했습니다. 종목코드문자열로 변환한 후, zfill() 함수를 사용해 앞자리를 0으로 채워 6자리로 맞췄습니다. 아래 출력결과를 보면 삼성전자의 종목코드가 '005930'으로 정상적으로 표시된 것을 확인할 수 있습니다.
import requests import pandas as pd def getCorpList(): url = 'https://kind.krx.co.kr/corpgeneral/corpList.do' data = { 'method': 'download', 'orderMode': '1', 'orderStat': 'D', 'searchType': '13', 'fiscalYearEnd': 'all', 'location': 'all', } r = requests.post(url, data=data) df = pd.read_html(r.content, header=0)[0] # 리스트 내부 요소 추출 df[0]코드와 합침 # 종목코드 컬럼을 문자열로 변환 후, 6자리로 채움 # astype은 데이터프레임 열의 타입을 문자열로 변환함, int는 정수, float df['종목코드'] = df['종목코드'].astype(str) # 열의 모든값을 6자리로 zfill 채움 앞에 0으로 채워줌 # .str은 Pandas에서 문자열 작업을 위한 액세서 df['종목코드'] = df['종목코드'].str.zfill(6) return df corpList = getCorpList() corpList
Python
복사

종목코드 순회

이제 종목코드열을 순회하며 각 종목데이터를 수집하겠습니다. 진행 상황을 파악하기 위해 print() 함수로 종목코드회사명을 함께 출력할 것입니다.
# 종목코드와 회사명 리스트 생성 codes = corpList['종목코드'].tolist() companies = corpList['회사명'].tolist() # 리스트를 사용하여 순회 for code, company in zip(codes, companies): print(f"처리중: {code} - {company}") # 여기에 각 종목별 데이터 수집 코드가 들어갈 예정 pass # 임시 패스 처리
Python
복사
위 코드는 tolist() 함수로 데이터프레임의 열을 리스트로 변환하고, zip() 함수를 통해 두 리스트를 동시에 순회합니다. 각 반복마다 종목코드회사명이 출력되어 데이터 수집 진행 상황을 실시간으로 확인할 수 있습니다. (tqdm이라는 라이브러리를 사용하면 print를 하지 않아도 현상황을 알수있습니다만 이부분은 다음에 추가 하겠습니다.)

데이터 저장하기

저장 방법론 페이지에서 설명한 parquet 형식을 사용하여 데이터를 저장할 예정입니다. 위의 종목코드 순회 코드에 FinanceDataReader를 통해 데이터를 요청하고, 이를 to_parquet으로 저장하는 로직을 추가할 것입니다.

data폴더 생성

데이터를 저장할 때 노트북이 있는 폴더에 바로 to_parquet으로 저장할 수도 있지만, 더 효율적인 관리를 위해 data 폴더를 생성하여 그 안에 데이터를 저장하겠습니다. data 폴더는 직접 만들거나 아래 코드를 사용하여 생성할 수 있습니다.
import os # 생성할 폴더 경로 folderPath = "data" # 폴더 생성 (필요할 경우만 생성) os.makedirs(folderPath, exist_ok=True)
Python
복사

데이터 저장 시작

코드를 통합하고 실행하면 데이터를 순차적으로 요청하고 저장할 수 있습니다. 간단하죠? 하지만 작업 완료 시점을 파악하기가 어렵습니다. 이를 해결할 수 있는 좋은 방법이 있는데, 바로 위에서 언급했던 tqdm 라이브러리입니다.

tqdm추가

tqdm은 Python에서 반복문의 진행 상황을 시각적으로 표시해주는 라이브러리입니다. 'tqdm'이라는 이름은 아랍어 'taqaddum'에서 유래했으며, '진행'을 의미합니다.
진행률을 퍼센트로 표시
예상 완료 시간 표시
처리 속도(초당 반복 횟수) 표시
진행 상태를 프로그레스 바로 시각화
pip install tqdm
Bash
복사
tqdm은 특히 대량의 데이터를 처리하거나 시간이 오래 걸리는 작업을 수행할 때 유용합니다. 사용자는 작업의 진행 상황을 실시간으로 모니터링할 수 있어 작업이 정상적으로 진행되고 있는지 쉽게 확인할 수 있습니다.

날짜체크

이미 오늘 데이터를 수집했다면 다시 수집할 필요가 없습니다. 따라서 파일이 저장된 시간을 확인하여 오늘 수집한 데이터가 있는 경우 데이터 수집을 건너뛰고 다음 종목 데이터를 수집하는 과정으로 넘어가겠습니다.

전종목 수집코드

코드는 ChatGPT에게 문의하시면 더 자세히 설명받을 수 있습니다. 중요한 것은 코드 자체가 아니라 이해하는 과정입니다. 위의 설명을 잘 따라와 주시기 바랍니다.
import os import requests import pandas as pd from datetime import datetime, timedelta import FinanceDataReader as fdr from tqdm import tqdm # 폴더 생성 folderPath = "data" os.makedirs(folderPath, exist_ok=True) # 상장법인목록 함수 def getCorpList(): url = 'https://kind.krx.co.kr/corpgeneral/corpList.do' data = { 'method': 'download', 'orderMode': '1', 'orderStat': 'D', 'searchType': '13', 'fiscalYearEnd': 'all', 'location': 'all', } r = requests.post(url, data=data) df = pd.read_html(r.content, header=0)[0] df['종목코드'] = df['종목코드'].astype(str) df['종목코드'] = df['종목코드'].str.zfill(6) return df # 오늘로부터 2년전의 날짜를 생성 def getStartAndEndDates(years=2): currentUtcTime = datetime.utcnow() currentKstTime = currentUtcTime + timedelta(hours=9) pastKstTime = currentKstTime - timedelta(days=365*years) # 결과 반환 return { "endDate": currentKstTime.strftime('%Y-%m-%d'), "startDate": pastKstTime.strftime('%Y-%m-%d') } corpList = getCorpList() #상장법인목록 date = getStartAndEndDates() #2년전 날짜와 현재날짜 딕셔너리 startDate = date['startDate'] #2년전날짜 endDate = date['endDate'] #오늘날짜 # 종목코드와 회사명 리스트 생성 codes = corpList['종목코드'].tolist() companies = corpList['회사명'].tolist() # 리스트를 사용하여 순회 for code, company in tqdm(zip(codes, companies), total=len(codes), desc="Processing Companies"): filePath = f"data/{code}.parquet" # 파일 존재 확인 if os.path.exists(filePath): # 파일 저장 날짜 확인 lastModified = datetime.fromtimestamp(os.path.getmtime(filePath)).strftime('%Y-%m-%d') if lastModified == endDate: # 오늘 저장된 파일이면 넘어감 continue df = fdr.DataReader(code, startDate) df.to_parquet(filePath)
Python
복사

노트북 파일

price.ipynb
3.5KB

활용방법

최종 저장파일은 당일 여러 번 실행해도 날짜 체크 로직 덕분에 단 한 번만 수행됩니다. 전체 코드를 정리하고 함수화한 뒤 스케줄러에 등록하면 매일 자동으로 실행되어 최신 데이터를 수집할 수 있습니다.
주가데이터는 일별로 기록되므로, 장 종료 시간에 맞춰 자동 수집되도록 설정하고 전처리 로직을 추가하면 다음 날 매수할 종목을 분석하는 등 다양한 투자 전략에 활용할 수 있습니다.