ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 증권 데이터 크롤링 - 네이버 증권 , KRX 활용해 종목별 차트 호가 데이터 저장하기
    데이터 분석 공부/파이썬 데이터 분석 2024. 4. 3. 16:02
    728x90

     

    네이버 증권 > 특정 주식의 차트 데이터를 가져와 보려고 합니다. 

    차트 데이터는 동적으로 움직임에 따라 새로운 response를 보이는데, 이 response를 확인해 어떤 API를 쓰는지 확인할 수 있습니다.

    # starttime, endtime, symbol은 시작, 종료날짜, 종목코드이므로 중괄호로 비워둠
    url = "https://m.stock.naver.com/front-api/v1/external/chart/domestic/info?symbol={}&requestType=1&startTime={}&endTime={}&timeframe=day"
    
    # 삼성전자 종목코드 005930
    r = requests.get(url.format('005930', '20230102', '20240402'))
    
    # eval : 함수는 문자열로 표현된 파이썬 표현식을 평가하고 실행하는 파이썬 내장 함수입니다. 
    # 이 함수는 문자열에 포함된 파이썬 코드를 실행하여 결과를 반환합니다.
    data = eval(r.text.strip())
    
    import csv
    f= open("./삼성전자.csv", 'w', newline='')
    write_stock = csv.writer(f)
    write_stock.writerows(data)
    f.close()

     

    writer 함수에 대한 공부

    더보기

    csv.writer() 함수는 CSV 파일을 작성하기 위한 객체를 생성합니다. 이 객체는 CSV 파일에 텍스트를 쓰는 데 사용됩니다. csv.writer() 함수에 파일 객체를 전달하여 해당 파일에 쓰기 작업을 수행할 수 있습니다.

    1. writer: csv.writer() 함수로 생성된 객체입니다. 이 객체를 사용하여 CSV 파일에 한 줄씩 데이터를 작성할 수 있습니다. writer 객체의 writerow() 메서드를 사용하여 하나의 행을 작성할 수 있습니다.
    2. writerows: csv.writer() 객체의 메서드 중 하나입니다. writerows() 메서드는 여러 개의 행을 한 번에 작성하는 데 사용됩니다. 이 메서드는 반복 가능한(iterable) 객체(예: 리스트, 튜플 등)를 인자로 받아서 해당 객체에 포함된 각 요소를 CSV 파일에 한 줄씩 작성합니다.

    따라서, write_stock.writerows(data)는 write_stock 객체를 사용하여 data에 포함된 여러 개의 행을 CSV 파일에 한 번에 작성하는 것을 의미합니다. 데이터의 각 행은 CSV 파일의 한 줄로 작성됩니다.

     

    앞으로 크롤링을 해 온 다음, 해당 파일을 저장할 폴더를 하나 생성해 줄게요.

    # 폴더 생성하기
    
    if not os.path.isdir('./stock'):
        os.mkdir('./stock')

     

    이번엔 KRX 사이트에서 모든 코스피 상장 주식의 종목코드를 가져와보려고 합니다 

    KRX 사이트

    크롤링 전, 사이트가 자바스크립트로 되어 있는지, 자바스크립트 없이도 가져올 수 있는지 확인해야 합니다.
    자바스크립트로 되어 있다면 requests.get 했을 때 자바스크립트 코드를 가져오게 되는데요.
    그러나 우리는 코딩의 결과로 나오는 데이터를 크롤링 해와야 하므로 API 값을 확인해야 합니다.

    조회 버튼 클릭 시 -> getJsonData.cmd 가 나옴 -> POST 방식으로 Request URL을 가져와야 합니다. 

     

     

    Payload 를 확인하여 어떤 정보를 요청해야 하는지 확인해줍니다.

    # KRX 에서 종목 데이터 URL 가져오기 
    url1 = 'http://data.krx.co.kr/comm/bldAttendant/getJsonData.cmd'
    
    payload = {
        'bld': 'dbms/MDC/STAT/standard/MDCSTAT01901',
        'locale': 'ko_KR',
        'mktId': 'STK',
        'share': '1',
        'csvxls_isNo': 'false'
    }

     

    여기까지 하고 r.status_code 확인해서 200대 번호가 나오는지 (정상인지) 확인해 봅니다.

    정상이라면 r.text 로 불러온 텍스트 내용을 확인해 봅니다.

     

    r.json() 을 하면 json 타입으로 변환해 줍니다. 

     

    json() 더 알아보기

    더보기

    json() 메서드는 requests 라이브러리의 Response 객체에 내장된 메서드로, HTTP 응답으로부터 JSON 형식의 데이터를 파싱하여 파이썬 객체로 변환합니다.

     

    위의 코드에서 r1은 requests.post() 메서드로 생성된 Response 객체입니다. 이 객체는 서버로부터 받은 HTTP 응답을 나타내며, .json() 메서드를 사용하여 해당 응답의 JSON 데이터를 파이썬 객체로 변환할 수 있습니다.

     

    따라서 data1 = r1.json()은 r1이 가리키는 HTTP 응답으로부터 JSON 형식의 데이터를 파싱하여 data1 변수에 파이썬 객체로 저장하는 것을 의미합니다. 이렇게 변환된 파이썬 객체를 통해 원하는 데이터에 액세스하고 처리할 수 있습니다.

     

    r.json().keys() 를 하면 딕셔너리가 갖고 있는 키 값을 확인할 수 있습니다. 어떤 키를 가져올지 확인했죠?

    지금 경우에서는 OutBlock_1 이 키입니다.

     

    # url1에서 텍스트 가져오기
    
    r1 = requests.post(url1, data=payload)
    data1 = r1.json()
    print((data1)['OutBlock_1'][:3])

     

    종목 데이터를 확인했다면, 앞에서 먼저 살펴본 네이버 주식 API 형식과 결합해서 크롤링 코드를 완성합니다.

    # 주식 종목 데이터 url 가져오기
    url2 = "https://m.stock.naver.com/front-api/v1/external/chart/domestic/info?symbol={}&requestType=1&startTime={}&endTime={}&timeframe=day"
    
    # 네이버 주식 api를 이용해서 종목 데이터 가져오기
    for d in tqdm(data1["OutBlock_1"][:200]):
        stock_name = d['ISU_ABBRV']  # 종목 이름 가져오기
        stock_code = d['ISU_SRT_CD'] # 종목 코드 가져오기
        r2 = requests.get(url2.format(stock_code, '20230102', '20240402'))
        data = eval(r2.text.strip())
        f = open("./stock/{}.csv".format(stock_name), "w", newline='')
        write_stock = csv.writer(f)
        write_stock.writerows(data)
        f.close()

     

    완성하면 ! 

    폴더를 열었을 때 이렇게 주식 호가 데이터가 종목별로 파일에 저장됩니다. 

     

    사용자 정의 함수를 정의하는 방식으로도 풀어봅니다.

    # dict comprehension 
    master = {x['ISU_SRT_CD'] : x['ISU_ABBRV'] for x in r1.json()['OutBlock_1']}
    
    # 사용자 정의 함수 
    
    def get_naver_stock(code, start_date, end_date):
        if not os.path.isdir('./stock'):
            os.mkdir('./stock')
            
        url = "https://m.stock.naver.com/front-api/v1/external/chart/domestic/info?symbol={}&requestType=1&startTime={}&endTime={}&timeframe=day"
        r = requests.get(url.format(code, start_date, end_date))
        data = eval(r.text.strip())
    
        f = open(f"./stock/{master[code]}.csv", 'w', newline='')
        write_stock = csv.writer(f)
        write_stock.writerows(data)
        f.close()

     

    에러가 발생할 확률이 높은 코드를 작성할 때, 에러 원인 확인하게 하기 

    : try, except 활용하기

    import csv 
    def get_naver_stock(code, start_date, end_date):
        """
        code -> 종목 코드 넣어 
        start_date -> 시작 날짜 
        end_date -> 끝나는 날짜
        """
        url = "https://m.stock.naver.com/front-api/v1/external/chart/domestic/info?symbol={}&requestType=1&startTime={}&endTime={}&timeframe=day"
        r = requests.get(url.format(code, start_date, end_date))
        data = eval(r.text.strip())
        
        # 폴더가 없어서 에러가 발생한다면... 
        try:
            f = open(f"./stocks/{master[code]}.csv", 'w', newline='')
        except Exception as e:
            print(e)
            os.mkdir("./stocks")
            f = open(f"./stocks/{master[code]}.csv", 'w', newline='')
        write_stock = csv.writer(f)
        write_stock.writerows(data)
        f.close()

     

     

    댓글

Designed by Tistory.