finacedatareader : 한국 주식 가격, 미국주식 가격, 지수, 환율, 암호화폐 가격, 종목 리스팅 등 금융 데이터 수집 라이브러리
tqdm : 작업의 진행 상태를 보여주는 라이브러리
trange()
: tqdm에서 제공하는 기능. 범위 내에서 진행 상황을 알려줌웹 스크래핑 시 서버에 부담을 주지 않기 위해 time.sleep()
을 이용해 서버에 텀을 두고 요청하는 것이 매너. 너무 빠르게 많이 요청 시 api가 차단될 수 있음
함수 내에서는 import 구문을 빼는 것이 나음. 함수 호출 때마다 import하기 때문에 비효율적임
개발자 도구 source code의 network 탭의 이해
키워드
html 파일 읽어오기 : pd.read_html(url, encoding="cp949")
결측 데이터 제거하기(axis 0:행, 1:열) : table[0].dropna()
데이터 프레임 합치기 : pd.concat([df1, df2, df3])
중복데이터 제거 : df.drop_duplicates()
과학적 기수법
날짜 column의 첫 row값 확인 : date = df.iloc[0]["날짜"]
파일로 저장하기 : df.to_csv(file_name, index=False)
파일 읽어오기 : pd.read_csv(file_name)
requests : HTTP for Humans
request 메서드 : 데이터 수집 시에는 두 가지 방법으로 거의 해결 가능
pd.read_html()
: table 테그 있어도 그냥 사용하면 안되는 이유?
-> 접근 권한을 막아놓음. 브라우저의 정상적인 요청이 아니기 때문에
-> requests 사용해서 헤더값 입력해서 불러옴
status code 200 : 정상적인 응답
request.get()
{"user-agent" : "Mozilla/5.0"}
를 헤더에 추가해 봇이 아닌 브라우저임을 알려줌셀레니움은 데이터 수집용으로 만들어진 라이브러리는 아니기 때문에 사용 권장 안함
Beautifulsoup : html, xml 등의 웹 문서를 파싱해서 원하는 정보를 찾고자 할 때 사용하는 라이브러리
.find_all()
: 해당 태그 정보를 모두 가져옴
.select()
: selector를 통해 태그를 구조화해서 정보를 가져옴
a
태그 : 하이퍼링크 정보
의사코드(Pseudo-code) : 코드 진행 과정을 단계별로 기록해 놓은 것
반복문으로 가져온 DataFrame들이 list의 형태로 저장된 것을 concat()
을 이용하여 합치면서 하나의 DataFrame으로 만들어줌
def get_item_list(item_code, item_name):
"""
일별 시세를 수집하는 함수
"""
# 데이터를 저장할 빈 변수 선언
page_no = 1
item_list = []
prev_day = ""
cols = ['종목코드', '종목명', '날짜', '종가', '전일비', '시가', '고가', '저가', '거래량']
while True:
# 한 페이지의 일별 시세 수집
df_item = get_day_list(item_code, page_no)
# 해당 데이터의 마지막 날짜를 가져옴
last_day = df_item.iloc[-1]["날짜"]
print(page_no, prev_day, last_day)
# 해당 데이터의 마지막 날짜와 이전 데이터의 마지막 날짜를 비교
# 맨 처음 데이터에서는 이전 데이터의 날짜(prev_day)가 없기 때문에 반복문 밖에서 초기화함
# 이전 데이터의 마지막 날짜와 현재 데이터의 마지막 날짜가 같다면 반복문 빠져나감
if last_day == prev_day:
break
# 현재 데이터의 날짜를 다음 턴에서 비교할 수 있게 변수에 값을 넣어줌
prev_day = last_day
# 수집한 일별 시세를 리스트에 추가
item_list.append(df_item)
# 다음 페이지 수집을 위해 페이지 번호 1 증가
page_no += 1
# 서버에 부담을 주지 않기 위해 쉬었다가 가져옴
time.sleep(0.01)
# 리스트로 저장된 데이터프레임 하나로 합침
df_day = pd.concat(item_list)
# 종목코드, 종목명 컬럼 추가
df_day["종목코드"] = item_code
df_day["종목명"] = item_name
# 미리 선언해둔 컬럼명으로 순서 변경
df_day = df_day[cols]
# 중복 제거
df_day = df_day.drop_duplicates()
# 마지막 날짜 내용 가져옴
date = df_day.iloc[0]["날짜"]
# 파일 이름 생성
file_name = f"{item_name}_{item_code}_{date}.csv"
# 파일 생성
df_day.to_csv(file_name, index=False)
# read_csv로 불러오기 위해 파일명 반환
return file_name
import time
item_code = "323410"
item_name = "카카오뱅크"
get_item_list(item_code, item_name)
>1 2022.09.15
>2 2022.09.15 2022.08.30
>3 2022.08.30 2022.08.16
>4 2022.08.16 2022.08.01
>5 2022.08.01 2022.07.18
>6 2022.07.18 2022.07.04
>7 2022.07.04 2022.06.20
>8 2022.06.20 2022.06.03
>9 2022.06.03 2022.05.19
>10 2022.05.19 2022.05.04
>11 2022.05.04 2022.04.20
>12 2022.04.20 2022.04.06
>13 2022.04.06 2022.03.23
>14 2022.03.23 2022.03.08
>15 2022.03.08 2022.02.21
>16 2022.02.21 2022.02.07
>17 2022.02.07 2022.01.19
>18 2022.01.19 2022.01.05
>19 2022.01.05 2021.12.21
>20 2021.12.21 2021.12.07
>21 2021.12.07 2021.11.23
>22 2021.11.23 2021.11.09
>23 2021.11.09 2021.10.26
>24 2021.10.26 2021.10.12
>25 2021.10.12 2021.09.24
>26 2021.09.24 2021.09.07
>27 2021.09.07 2021.08.24
>28 2021.08.24 2021.08.09
>29 2021.08.09 2021.08.06
>30 2021.08.06 2021.08.06
>'카카오뱅크_323410_2022.09.28.csv'
api 메서드 : GET, POST, PUT, DELETE <=> CRUD
expand = True
: 데이터프레임 형태로 반환
datetime : 날짜 관련 처리 라이브러리
크롬 브라우저에서 속성으로 들어갔을 때 데이터를 받아오는 경로를 알 수 있는 탭
-> network
<td class="title">
이라 표현된 태그 안의 텍스트를 수집하고자 했을 때 HTML 태그를 찾는 적절한 BeautifulSoup 코드는?
-> html.select("td.title")
df.reset_index(drop=True)
: 인덱스 값 다시 생성 후 기존 인덱스 제거