본문 바로가기
파이썬 (투자분석용)/Pandas 및 python 일반

[python] 한국증시(코스피, 코스닥) 주가정보 추출 feat. by 네이버금융

by amAToRoi 2022. 2. 1.
반응형

    1. 주가란?


    당연하게도 거래가 목적인 주식의 기본 정보는 주가이다.

    물론, 이와 반대로 회사의 소유주가 되는 의미가 곧 거래임으로 주가는 보조적 위치에 있다는 관념도 존재한다. 토스 증권의 거래 방식이 바로 이런 아이디어를 기반으로 한다.

    주식은 발행증권의 수와 가격으로 이루어져있다.
    거래금액에 따라 가격이 변동하기도 하지만 발행증권의 수가 달라지면 가격이 의도적으로 조정받기도 한다.
    이를 “수정주가”라고 한다. 어렵게 생각할 필요없이, 평소에 보던 주가는 모~두 수정주가라고 생각해도 무방하다. "한때 삼성전자가 400만원할 때가 있었지" 라는 고리타분한 얘기는 모두 수정하기 이전의 주가 얘기이다.

    네이버금융(https://finance.naver.com)에서는 수정주가를 제공하고 있으며, 웹에서 줏어오기 편하다.

    물론, 종목코드를 추출한 한국거래소(https://data.krx.co.kr)에서 주가정보를 추출할 수 도 있다.
    "[12001] 전종목시세", "[12003] 개별종목 시세 추이"와 내 블로그의 다른 포스트를 참고하기 바란다.
    한국증시(코스피, 코스닥) 종목코드 받아오기

     

    2. 네이버금융 주가정보 추출하기

    필요한 대부분의 정보를 제공하는 네이버에서 주가정보를 스크래핑하자

    네이버금융에서 특정종목(예: 삼성전자)을 선택한 후, 시세로 들어가보자
    https://finance.naver.com/item/main.naver?code=005930

    웹 스크래핑(web scrapping)은
    python, R 등의 프로그래밍 언어에 대한 지식을 기반으로 HTML, JSON, 과 같은 웹의 구성에 대한 이해와 웹 서버와 클라이언트간의 커뮤니케이션에 대한 기본적인 지식이 있어야 가능한 기술이지만
    아~ 모르겠고, PYTHON  Requests로 그냥 따라해 보자.

       가. 스크랩할 페이지 찾아내기  

    개발자도구로 차트를 선택 시 동작을 살펴보면, siseJson이 보인다.
    개발자도구 - Network는 감사한 툴

    무작정 크롬의 개발자도구(단축키 F12)를 켜고 네이버금융 사이트를 뒤져보자.
    차트 페이지에서 그럴 듯한 주소(URL)을 찾았다!!!!

    sise(시세) 라고 이름을 지어주신 개발자 님께 감사의 인사

    주소를 복사해서 웹브라우저에서 확인해보자.
    https://api.finance.naver.com/siseJson.naver?symbol=005930&requestType=1&startTime=20201011&endTime=20210602&timeframe=day

    위 주소 실행시 화면
    유레카!

    원하는 정보를 제공하는 페이지를 찾았다. 이제 페이지 구성을 분석해보자.

    https://api.finance.naver.com/siseJson.naver?
    symbol=005930&requestType=1&startTime=20201011&endTime=20210602&timeframe=day

    이 주소는 시세정보를 Json형태로 가져오는 모듈과 모듈에 제공하는 파라미터값을 정의한 부분으로 나뉜다.

    물음표(?) 뒤가 파라미터 영역이며, 엠퍼센트(&)로 각 파라미터를 구분한 것으로 보인다.

    파란색의 모듈 부분은 수정할 필요가 ㅇ벗다. 관심도 ㅇ벗다.

    파라미터 key와 value 설명
    symbol=005930 종목코드이겠지? 삼성전자의 종목코드는 005930이다.
    requestType=1 일단 무시하자. (참고로 2도 있다.)
    startTime=20201011 시작날짜로 보인다. YYYYMMDD형식으로 8자리 숫자형태로, 2020년 10월 11일 인 듯
    endTime=20210602 상동
    timeframe=day 날짜별데이터를 의미, month 또는 week 가능
    파라미터를 바꾸어가며 웹브라우저에 값을 넣어보자. 
    스크래핑을 위한 가장 중요한 행위는 여기까지다. 나머지는 잔재주에 불과하다.

       나. Requests 설치하기  

    $ pip install requests

    requests는 python에서 미친듯이 유명한 패키지 중 하나로, 웹서버로 요청(request)하고 웹서버가 응답(response)하는 일련의 행위를 python에서 가능하게 한다.

    조악하게 설명하자면...나도 잘 모르니
    크롬과 같은 웹브라우저에서 우리가 주소를 넣으면 = 웹서버로 해당 주소의 데이터를 요청(request)하고
    크롬에서 웹페이지가 눈에 보이는 것 = 웹서버가 응답한(response) 데이터를 브라우저가 표시한 것

    urllib와 같은 내장 패키지가 있지만, 모두가 사랑하는 requests 쓰자.
    익숙해지면, 차단방지라던가 후처리 라던가... 쓰일 데가 많아질 것이다.

       다. python으로 requests 사용하기  

    requests에서 주로 사용하는 요청방식은 2가지이다. 바로, Get과 Post가 바로 그것.
    get은 대상 url(주소)를 그대로 요구하는 것이며,
    post는 대상 url에 변수를 제출, 수정, 요구하는 등 서버에 보다 복잡한 요구를 하는 것인데...

    웹브라우저 및 개발자도구에서 확인가능한 url을 건드리는 것으로 필요한 데이터를 수집할 수 있다면 get을 쓰나 post를 쓰나 관계없다. 바로 이번과 같은 경우다. 눈이 밝은 사람은 개발자도구에서 "POST"를 발견했겠지만, 그냥 GET 쓰자.

    import requests as rq
    url = 'https://api.finance.naver.com/siseJson.naver?symbol=005930&requestType=1&startTime=20191011&endTime=20210602&timeframe=day'
    res = rq.get(url).text
    
    print(res) # 찬찬히 살펴보면 웹브라우저에 확인한 데이터와 같음을 알 수 있다.

    일단 웹브라우저에서 눈으로 보이는 데이터는 그대로 가져왔다.
    남은 것은 핸들링 가능한 형태로 처리하는 것 (python list 데이터 구조를 바꿔놓자.)

    Hint. requests 패키지는 text가 아니라 json으로 데이터를 수집할 수 있는 모듈을 제공하지만, naver의 웹서버에서 응답한 데이터구조와 python code가 충돌되는 부분이 있어 이를 수정하는 방식으로 적용하기 위해 json 패키지를 추가로 import하였다.
    import json
    data = res.replace("'", '"').strip() # 홑따옴표 → 쌍따옴표 + 빈칸지우기
    data = json.loads(data)              # JSON 형태를 Python List로 변환
    
    print(data)         # 내용물 확인, 2차원 List 형태 데이터임
    print(type(data))   # <class 'list'> 임을 확인

    만약, json으로 변환하지 않고 바로 리스트 형태로 바꾸려고 한다면, ast 패키지를 사용하면 된다.

    import ast
    data = res.replace("'", '"').strip() # 홑따옴표 → 쌍따옴표 + 빈칸지우기
    data = ast.literal_eval(data)              # Python List로 변환
    
    print(data)         # 내용물 확인, 2차원 List 형태 데이터임
    print(type(data))   # <class 'list'> 임을 확인

       라. 위 코드 합체 정리~~ 끝~~   

    import requests
    import json
    
    url = 'https://api.finance.naver.com/siseJson.naver?symbol=005930&requestType=1&startTime=20191011&endTime=20210602&timeframe=day'
    res = requests.get(url)
    data = res.text.replace("'", '"').strip()
    data = json.loads(data)

     

    3. 나머지 공부

    위 코드는 퀀트를 위한 데이터 수집 단계의 일부분에 불과하다.
    다른 종목도 추출해야 하고, 이를 자동화 하려면 무엇이 더 필요할까?

    1. f-string 사용
    2. requests의 parameter 또는 data를 사용

    하는 방법으로 가능하다. 

    범용성이 크다는 점에서 f-string을 사용하길 권한다. 2번 방식은 다른 상황에서도 배울 일이 있을 테니...

     

    이 방식을 기초로 차트를 그려보고 싶다면, 아래 포스트를 참고하자

     

    캔들(candlestick) 차트 그리기

    ★ 프로젝트: Bull Market으로 만들고 있는 사용자 함수 중, GetPriceList( ) 를 활용하여 Plotly 의 Candlestick 차트를 그리는 법을 설명하는 포스트로 GetPriceList()에 대해 정리하고 설명하는 것을 목적함 ☆.

    amatoroi.tistory.com

     

    반응형

    댓글