[TIL] 22.09.28

문종현·2022년 9월 28일
0

TIL

목록 보기
5/119

👉 오늘 한 일

  • 웹 스크래핑 실습(주식 종목 - 네이버 금융뉴스)
  • 웹 스크래핑 실습(네이버 금융 개별종목 수집)


웹 스크래핑 실습(주식 종목 - 네이버 금융뉴스)

finacedatareader : 한국 주식 가격, 미국주식 가격, 지수, 환율, 암호화폐 가격, 종목 리스팅 등 금융 데이터 수집 라이브러리

FinanceData/FinanceDataReader: Financial data reader

tqdm : 작업의 진행 상태를 보여주는 라이브러리

  • trange() : tqdm에서 제공하는 기능. 범위 내에서 진행 상황을 알려줌
    • tqdm(range())와 같음

웹 스크래핑 시 서버에 부담을 주지 않기 위해 time.sleep()을 이용해 서버에 텀을 두고 요청하는 것이 매너. 너무 빠르게 많이 요청 시 api가 차단될 수 있음

함수 내에서는 import 구문을 빼는 것이 나음. 함수 호출 때마다 import하기 때문에 비효율적임

개발자 도구 source code의 network 탭의 이해

  • .css : 웹의 스타일 관련 파일
  • 각종 이미지 파일
  • XHR, js, 문서 형태의 파일 등

키워드

  • html 파일 읽어오기 : pd.read_html(url, encoding="cp949")

    • 내부에서 테이블 테그를 찾아줌
  • 결측 데이터 제거하기(axis 0:행, 1:열) : table[0].dropna()

  • 데이터 프레임 합치기 : pd.concat([df1, df2, df3])

  • 중복데이터 제거 : df.drop_duplicates()

  • 과학적 기수법

    • 1.210000e+02 => 121
  • 날짜 column의 첫 row값 확인 : date = df.iloc[0]["날짜"]

  • 파일로 저장하기 : df.to_csv(file_name, index=False)

  • 파일 읽어오기 : pd.read_csv(file_name)

웹 스크래핑 실습(네이버 금융 개별종목 수집)

requests를 통한 HTTP 요청

requests : HTTP for Humans

  • 작은 브라우저로 웹사이트를 읽어오는 것이 목적

request 메서드 : 데이터 수집 시에는 두 가지 방법으로 거의 해결 가능

  • GET
    • 필요한 데이터를 query string에 담아 전송함
    • 보통 url 전송
  • POST
    • 전송할 데이터를 HTTP 메시지의 Body의 form data에 담아 전송함
    • 보통 버튼을 눌러 전송하는 데이터 전송(검색어, 개인정보 입력 등)

pd.read_html() : table 테그 있어도 그냥 사용하면 안되는 이유?
-> 접근 권한을 막아놓음. 브라우저의 정상적인 요청이 아니기 때문에
-> requests 사용해서 헤더값 입력해서 불러옴

status code 200 : 정상적인 응답

request.get()

  • {"user-agent" : "Mozilla/5.0"}를 헤더에 추가해 봇이 아닌 브라우저임을 알려줌

셀레니움은 데이터 수집용으로 만들어진 라이브러리는 아니기 때문에 사용 권장 안함

BeautifulSoup 을 통한 table 태그 찾기

Beautifulsoup : html, xml 등의 웹 문서를 파싱해서 원하는 정보를 찾고자 할 때 사용하는 라이브러리

.find_all() : 해당 태그 정보를 모두 가져옴

  • 어트리뷰트(name, class 등) 지정 가능
  • e.g. soup.find('div').find('p')

.select() : selector를 통해 태그를 구조화해서 정보를 가져옴

  • selector : 개발자 도구에서 소스코드의 경로값
  • e.g. soup.select_one('div > p')

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")

  • html.select("td > title") : 하위 태그 가져옴
  • html.select("td#title") : ID값 가져옴

df.reset_index(drop=True) : 인덱스 값 다시 생성 후 기존 인덱스 제거

profile
자라나라 새싹새싹🌱

0개의 댓글