python

[Python] Pandas 데이터 프레임 (엑셀, 크롤링)

vhxpffltm 2020. 6. 14. 17:44

어쩌다 책을 찾다보니 파이썬 주식 데이터와 관련된 책이 있었고 주식을 하나도 모르던 내가 예전에 아버지께서 이 회사의 주식이 엄청 오를거다. 하시는 말씀을 기억하면서

 

파이썬으로 주식 데이터를 크롤링하고 저장하고 한번 나타낸 후, Keras를 통한 학습으로 어떤지 결과를 알고 싶어 금방 하게 되었다.

 

주식 데이터를 크롤링하고 저장하는것 까지만 진행해보자. 기본 예제코드는 첫 번째 Refernce를 모두 참고하였다.

 

먼저 크롤링을 해보자. 크롤링은 beautifulsoup 등의 크롤링 모듈을 사용해도 되지만, 여기서는 Pandas의 기본 크롤링을 사용하였다.

 

Pandas 설치

패키지를 설치하면 된다. pip를 사용해 설치해도 되고 필자는 파이참 IDE를 사용하는데 해당 프로젝트의 setting에서 패키지를 설치하였다.

 

거래소 코드 가져오기

Reference의 내용대로 상장법인목록을 크롤링하여 그 중에서 원하는 기업을 찾아 그 곳의 '종목코드'를 가져온다. 

pandas의 pd.read_html("URL주소") 로 가져올 수 있다. 이 메서드는 HTML 태그의 table태그를 찾아 자동으로 데이터프레임을 만들어주는 강력한 메서드이다. table이 여러개라면 리스트 형태로 각 데이터들을 저장한다.

 

문제는 이 주식관련 데이터들을 계속해서 API를 호출하여 시도하거나 비윤리 및 상업적 목적으로 이용되면 법적으로 문제가 될 수 있기에 필자는 해당 데이터를 크롤링 테스트만 하고 정보를 엑셀 파일로 저장하였다.

 

그럼 크롤링한 데이터를 어떻게 엑셀로 저장할까?

 

pd.to_excel("경로",sheet_name=) 메서드를 사용하여 크롤링한 데이터를 바로 엑셀파일에 저장한다. 그리고 저장된 엑셀 파일을 활용한다. 상장법인 데이터는 URL을 통해 바로 다운받을 수 있으므로 이 과정은 생략해도 좋다. 여기서는 확인하고자 하는 기업의 종목코드를 가져오는것이 목표이다.

 

'http://kind.krx.co.kr/corpgeneral/corpList.do?method=download&searchType=13

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def stock_list():
    code_df = pd.read_excel('stock_list.xlsx',sheet_name='stock_list')
    #KRX에 크롤링하지말고 상장 회사는 파일을 읽어들임
    #naver_rise = pd.read_html('https://finance.naver.com/sise/sise_rise.nhn',encoding='EUC-KR')
    #네이버 주식의 인코딩 방식에 따라 맞춰야 한글이 안깨짐
 
    # 6자리를 맞춰주기 위해 설정해줌
    code_df.종목코드 = code_df.종목코드.map('{:06d}'.format)
 
    # 필요없는 column들은 제외해준다.
    code_df = code_df[['회사명''종목코드']]
    #naver_rise= naver_rise[1]
 
    #naver_rise = naver_rise[['종목명','현재가','전일비','등락률']]  #메인의 최근 주가 상승 내용 가져옴
 
    #한글로된 컬럼명을 영어로 바꿔준다.
    code_df = code_df.rename(columns={'회사명''name''종목코드''code'})
    #print(code_df)
    #print(code_df2)
    return code_df
cs

 

위 코드에서 return 하는 값인 종목코드를 중심으로 보면 된다. 주석처리는 필자가 네이버 주식 홈페지의 어떤 메인부분을 데이터프레임으로 저장하고자 하는 실습 과정이 포함되어 있다. 

*여기서 위의 네이버 금융 페이지를 크롤링할때 인코딩에 주의해야 한다. 인코딩이 없을 때 실행하면 한글이 깨진 문자들로 나오며 네이버 페이지의 인코딩 방식인 'EUC-KR'을 맞춰주어야 한다.

 

 

주식 정보 크롤링

이제 네이버 금융에서 원하는 기업의 주식 정보를 가져와보자. 위와 비슷하게 하는데 해당 페이지를 보면 정보의 주소가 page별로 구성되어 있다. 여기서도 먼저 크롤링을 한번 진행하여 Pandas 데이터프레임에 먼저 저장을 하고 저장된 Pandas 데이터 프레임을 엑셀로 저장한다.  코드로 한번 보자

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def save_excel(df):
    df.to_excel('E:/pycharmproject/untitled/stock/Africa.xlsx',sheet_name="sheet1",index=False)
 
def get_url(item_name, code_df):
    code = code_df.query("name=='{}'".format(item_name))['code'].to_string(index=False)
    code = code.strip()
    print(code)
    #url = 'http://finance.naver.com/item/sise.nhn?code={code}'.format(code=code)
    url_day = 'http://finance.naver.com/item/sise_day.nhn?code={code}'.format(code=code)
    print("요청 URL = {}".format(url_day))
    return url_day
    # 아프리카의 데이터 url 그리고 일자별 데이터 가져옴
 
 
def africa(code_df):
    item_name='아프리카TV'
    #url_day = get_url(item_name, code_df) # 데이터를 담을 df라는 DataFrame 정의
    df , df_url= pd.DataFrame(),pd.DataFrame()
    #print(df)
 
    # 웹 페이지에서 크롤링을 통해 20페이지까지의 데이터를 저장
    # for page in range(1, 21):
    #     pg_url = '{url}&page={page}'.format(url=url_day, page=page)
    #     df_url = df_url.append(pd.read_html(pg_url, header=0)[0], ignore_index=True)
    #     #print(pg_url,df_url,end=" ")
 
    # 결측값이 있는 행을 제거, 이게 없으면 0번째 컬럼에 Nan 으로 데이터가 없는게 뜸
    #df_url = df_url.dropna()

    # 한글로 된 컬럼명을 영어로 바꿔줌
    #df_url = df_url.rename(columns={'날짜': 'date', '종가': 'close', '전일비': 'diff', '시가': 'open', '고가': 'high',
    #                            '저가': 'low', '거래량': 'volume'})
    # 데이터의 타입을 int형으로 바꿔줌
    #print(df_url.columns)
    #df_url = df_url.fillna(0)
    #df_url[['close', 'diff', 'open', 'high', 'low', 'volume']] \
    #    = df_url[['close', 'diff', 'open', 'high', 'low', 'volume']].astype(int)
    # 컬럼명 'date'의 타입을 date로 바꿔줌
    #df_url['date'] = pd.to_datetime(df['date'])
    # 일자(date)를 기준으로 오름차순 정렬
    #df_url = df_url.sort_values(by=['date'], ascending=True)
 
    df_url = pd.read_excel("E:/pycharmproject/untitled/stock/Africa.xlsx",sheet_name="sheet1")
 
    # 상위 5개 데이터 확인하기 
    print(df_url.head())
    save_excel(df_url)
 
 
cs

 

우선 위 코드에서 주석처리는 크롤링하는 부분과 데이터 칼럼명을 바꾸는 부분이다. 아프리카TV의 데이터를 저장할 것이고 크롤링을 위해 get_url() 이라는 함수가 있다. 

code 변수에 종목코드값을 저장하고 url_day 변수에 이제 크롤링할 주소를 위와 같이 넣는다.

이제 df_url 변수에 20페이지 까지의 데이터를 반복문을 통해 넣어주는 과정이다. 칼럼명을 변경하는 것은 Reference의 내용을 그대로 사용하였는데 오류가 발생할 수 있다. 오류 부분은 넘어가고 칼럼명만 바꾼다. 데이터 프레임 상위 5개를 출력하면 아래와 같다. 

엑셀로 저장할때 다른 다양한 옵션들을 줄 수 있다. 여기서는 해당 데이터 프레임을 바로 엑셀로만 저장하면 되기에 옵션들을 생략한다. 

 

 

날짜별 데이터들이 위와 같이 예쁘게 저장되었으며 이것을 엑셀로 저장한다.

 

이제 이것을 바탕으로 close에 대한 데이터를 그려본다. 필자의 개발환경은 쥬피터 노트북이 아닌 Python이라서 Python의 matplotlib를 간단하게 사용하였다. 이 패키지를 설치한다.

1
2
3
4
5
6
7
8
df2 = df_url[['date','close']]
 
    df2.plot()
    plt.title("Africa Stock")
    plt.xlabel("시간")
    plt.ylabel("value")
    plt.plot(df_url.date,df_url['close'])
    plt.show()
cs

 

먼저 원래의 df_url 데이터 프레임중 date와 close만을 따로 저장하였다. plot() 함수를 통해 그림을 그릴 수 있다.

x축에 date를 표시하고 싶었지만 아직 matplotlib 와 필요한 부분들은 수정하지 않았다. 오른쪽 하단에 보면 마우스 커서에 따른 x,y 값이 표시된다. 2019년 9월 30일의 close 가격을 확인할 수 있다.

 

 

중요한것은 데이터를 크롤링해서 엑셀로 저장하고 그것을 표시한 것이다. 이제 이 데이터와 Keras를 가지고 실험을 해봐야 하는데 잘 할 수 있일지 의문이다. 그런데 2년전 내가 조사할때 주가가 3만원대 였는데... 엄청나게 올랐다.

 

Reference

https://excelsior-cjh.tistory.com/109?category=975542

https://wikidocs.net/21047

https://wikidocs.net/4371