언빌리버블티
[KDT] Python 웹 스크래핑으로 네이버 금융 개별종목 데이터 수집 본문
멋쟁이 사자처럼 AI스쿨 3주차
: requests & BeautifulSoup 를 활용한 네이버 금융 국내 증시사이트 Web Scraping
item_name = "카카오뱅크"
save_csv(item_name)
이렇게 단 두 줄의 코드로 내가 원하는 기업의 일별시세 정보 데이터를 수집하는 방법에 대해 알아보자 !
함수 구조
- save_csv(종목명) : 종목 코드 할당, 데이터프레임 리스트 concat 및 csv 파일로 변환
- get_item_list(종목 코드, 종목명) : 전체 페이지 데이터 수집 및 데이터 프레임 리스트 반환
- get_day_list(종목코드, 페이지 번호) : url 생성 및 개별 페이지 데이터 반환
- get_item_list(종목 코드, 종목명) : 전체 페이지 데이터 수집 및 데이터 프레임 리스트 반환
라이브러리 로드
import pandas as pd
import requests
import FinanceDataReader as fdr
import time
- pandas : 데이터 처리 및 분석 라이브러리
- 행 * 열로 이루어진 DataFrame을 다룬다.
- requests : 서버에 http 요청을 보내는 모듈로 인터넷 상의 html 문서를 요청하여 받아온다.
- FinanceDataReader : 한국&미국 주식가격 , 지수, 환율, 암호화폐 가격, 종목 리스팅 등 금융 데이터 수집 라이브러리
- time : API 불러올 때 time sleep 을 걸어 어느 정도 텀을 주고 출력하는 것이 예의
수집할 url 할당하기
df_krx = fdr.StockListing("KRX")
item_name = "카카오뱅크"
item_code = df_krx.loc[df_krx["Name"] == item_name, "Symbol"].values[0]
page = 1
url = "https://finance.naver.com/item/sise_day.naver?code={item_code}&page={page_no}"
- fdr의 StockListing 메서드를 통해 한국 거ㅓ래소 상장 회사 정보를 불러온다.
- FinanceDataReader 로 불러온 내가 원하는 종목의 item_code를 받아온 뒤 쿼리 스트링 url에 할당한다.
ex ) 삼성전자(code=005930) 일별 시세 페이지의 10번째 페이지에 대한 HTML요청
데이터 수집하기
requests를 통한 HTTP 요청
response = requests.get(url, headers = {"user-agent":"Mozilla/5.0"})
response
- requests .get( url , header = '' ) : headers 옵션의 user-agent 를 Mozilla/5.0 로 지정하여 로봇이 아님을 알려주고 html 문서를 요청한다.
pandas로 데이터를 DataFrame 형식으로 받아오기
table = pd.read_html(response.text)
- encoding : cp949 (한글 인코딩). 디폴트 값은 utf-8 이며, 네이버의 일별 시세는 cp949 인코딩으로 불러올 수 있다.
- pd.read_html() : 받아온 html 문서에서 table tag를 읽어 반환한다.

temp = table[0].dropna().reset_index(drop='index')
temp
- dropna() : table[0] 의 NaN값을 제거한 뒤 데이터프레임 변수 생성
- reset_index(drop='index') : 데이터 프레임 인덱스를 초기화하고 기존에 있던 인덱스 변수는 남기지 않고 제거한다.
페이지 별 데이터 수집하기
초기값 설정하기
page_no = 1
item_list = []
prev_day = None
- page_no : 페이지 1부터 맨 마지막 n까지 탐색하기 위해 할당
- item_list : 맨 끝까지 탐색해서 불러온 DataFrame들을 모두 저장
- prev_day : 날짜를 비교하여 break를 걸어주기 위해 할당
- 각 페이지의 맨 마지막 데이터의 저장 날짜와 같아지면 while문을 탈출한다.
- last_day 변수에 저장된 값인 "맨 처음 (오래된) 불러온 데이터 날짜"가 될 때까지 반복한다.
- 각 페이지의 맨 마지막 데이터의 저장 날짜와 같아지면 while문을 탈출한다.
반복문(While)을 사용하여 페이지의 끝까지 탐색하여 데이터 수집하기.
While True:
df_item = get_day_list(item_code, page_no)
last_day = df_item.iloc[-1]["날짜"]
- get_day_list(item_code, page_no): 입력한 종목 번호+페이지 넘버에 따른 url로 만든 데이터 프레임을 반환하는 함수
- last_day : 데이터프레임 df_item에서 저장된 날짜가 가장 오래된 데이터 저장
-
- while 탈출 조건을 지정하기 위한 변수
- iloc : 인덱스 번호를 기준으로 데이터 행에 접근
-
조건문 (while문 break) 지정
if last_day == prev_day:
print(f'{page_no-1} 페이지가 마지막 페이지입니다.')
break
- 일별 시세이기 때문에 현재 날짜와 페이지 맨 마지막에 저장된 날짜를 비교한다.
- 맨 마지막 (날짜) 데이터를 불러오고 break 한 뒤 다음 페이지로 넘어간다.
각 페이지 별 데이터 append 및 코드 진행 사항 출력
prev_day = last_day
item_list.append(df_item)
if not page_no % 10:
print(page_no, prev_day, last_day)
page_no += 1
time.sleep(1)
- 이전 페이지 마지막 줄 날짜 last_day를 현재 페이지의 비교 날짜로 지정한다.
- 페이지 호출 횟수가 10씩 늘어날 때마다 진행사항(현재 불러온 데이터 저장 날짜, 이전 데이터 저장 날짜) 출력
- item_list.append() : item_list 에 가져온 페이지 별 데이터를 추가해준다.
- time.sleep(1) : 페이지 데이터를 불러오는 시간 간격을 1초로 둔다.
- API 호출 시 매너 : 기간이 긴 데이터를 수집할때는 서버에 부담을 주지 않기 위해 time.sleep()값 지정
- While 문 탈출 후 전체 페이지 데이터가 저장된 item_list 리스트 반환
수집한 데이터를 CSV파일로 저장하기
데이터 url 생성 및 전체 페이지 데이터를 수집하는 하나의 함수를 호출
df_krx = fdr.StockListing("KRX")
item_code = df_krx.loc[df_krx["Name"] == item_name, "Symbol"].values[0]
item_list = get_item_list(item_code, item_name)
반환된 item_list를 하나의 데이터프레임으로 합치기
df_day = pd.concat(item_list, ignore_index=True)
전체 데이터 변수명 정리 & 중복 데이터 삭제 & 인덱스 초기화
cols = ['종목코드', '종목명', '날짜', '종가', '전일비', '시가', '고가', '저가', '거래량']
df_day['종목코드'] = item_code
df_day['종목명'] = item_name
df_day = df_day[cols].drop_duplicates().reset_index(drop=True)
- 종목 코드와 종목명이라는 파생 변수를 생성한 뒤 item_code와 item_name을 입력
- df_day = df_day[cols] : DataFrame columns의 이름 순서를 바꿔준다.
- drop_duplicates() : 데이터의 중복을 제거한다.
- row들 끼리 data를 비교한 뒤 같은 값이 있을 경우 row 전체를 삭제한다.
- reset_index(drop=True) : index를 초기화한 뒤 이전 index 변수는 따로 남기지 않고 drop한다.
데이터 프레임을 CSV 형태 파일로 저장하기
date = df_day.iloc[0]["날짜"]
file_name = f'{item_name}_{item_code}_{date}.csv'
df_day.to_csv(file_name, index = False)
print('done')
- df.to_csv() : csv파일로 저장한다.
- index 옵션을 False로 두어 DF의 기본 index가 저장되지 않도록 한다.
파일명은 종목명_종목코드_API호출날짜.csv 로 저장한다.
- index 옵션을 False로 두어 DF의 기본 index가 저장되지 않도록 한다.
데이터 읽어오기
return pd.read_csv(file_name).head()
- pd.read_csv(파일명) : 파일을 읽어와서 데이터가 잘 저장되었는지 확인한다.
- head() : 데이터를 위에서부터 5개만 출력
Result
# 원하는 기업명을 item_name 으로 입력하여 일별시세정보 데이터 수집
item_name = "펄어비스"
save_csv(item_name)
10 2022.05.04 2022.05.04
20 2021.12.07 2021.12.07
30 2021.07.12 2021.07.12
40 2021.02.17 2021.02.17
50 2020.09.17 2020.09.17
60 2020.04.24 2020.04.24
70 2019.11.28 2019.11.28
80 2019.07.04 2019.07.04
90 2019.02.08 2019.02.08
100 2018.09.06 2018.09.06
110 2018.04.11 2018.04.11
120 2017.11.14 2017.11.14
124 페이지가 마지막 페이지입니다.
done

124개의 펄어비스 일별시세 페이지에서 총 1237개의 데이터를 수집해보았다 !
'Data Science > KDT' 카테고리의 다른 글
[KDT] 내 거친 성적과 불안한 공교육💦 : 대한민국 사교육 환경 변화와 원인 분석 (4) | 2022.10.27 |
---|---|
[KDT] 공공데이터를 활용한 서울시 대중교통 이용현황 분석 - (2) Seaborn과 matplotlib을 활용한 시각화 (0) | 2022.10.27 |
[KDT] 공공데이터를 활용한 서울시 대중교통 이용현황 분석 - (1) 데이터 수집 및 전처리 (0) | 2022.10.27 |
[KDT] YouTube API를 활용하여 수집한 데이터 분석하기 (2) KoNLPy 단어 형태소 추출 & WordCloud 시각화 (0) | 2022.10.05 |
[KDT] YouTube API를 활용하여 영상 데이터 리스트업하기 (1) YouTube API 호출하기 (0) | 2022.10.04 |
Comments