본문 바로가기
방구석코딩/주식 크롤링 분석

[파이썬] 주식 데이터 크롤링(6) - 웹 페이지 데이터 가져오기 (for문)

by 석세상 2024. 7. 12.
반응형

파이썬을 주식 데이터 크롤링을 위해서는 앞부분까지는 웹 브라우저에서 실행 및 제어하는 부분이었다면, 이제는 이렇게 원하는 페이지의 정보를 파이썬으로 데이터를 가져오는 영역이다.

 

데이터 가져오기

먼저 데이터를 가져오려는 주소를 p_url에 입력하고 browser.get을 통해 해당 주소를 입력한다. 여기서 우리는 1페이지에서 45페이지까지 변경하면서 데이터를 가져와야 하기 때문에 page= 뒷부분에 1,2,3,4,... 마지막 페이지 번호까지 변경이 필요하다. 

 

이때 url 주소는 문자이기 때문에 문자로 변경하는 str문을 써주고 앞의 url 주소와 결합을 위해서 + 를 이용한다.

p_url = 'https://finance.naver.com/sise/sise_market_sum.naver?sosok=0&page='

browser.get(p_url + str(1))                # http 주소는 문자이기 때문에 str을 이용하여 숫자를 문자로 변경해줘야함    
df = pd.read_html(browser.page_source)
df

 

다음은 웹 페이지의 있는 정보를 가져오기 위해서는 데이터를 가져오는 판다스 패키지를 이용해야 한다. 앞에서 pandas 패키지명을 pd로 별칭을 줬기 때문에 pd.read_html이라는 명령어를 이용한다.

 

다음으로 괄호 안에는 해당 브라우저의 page_source 명령어로 데이터를 가져온다. 그러면 df를 실행해주면  결과는 아래와 같이 확인할 수 있다.

 

붉은색으로 표시되어 있는 부분은 경고 표시인데 향후에 다음 버전이 나올 때 read_html이라는 명령문이 제거되기 때문에 다른 방법을 이용하라는 것이다. 하지만 현재는 문제가 없기 때문에 향후에 변경하기로 하고 그냥 사용해주기로 한다.

붉은색 아래 부분을 보면 [] 표시로 되어있는 부분이 있는데 현재 우리가 불러온 데이터가 몇개의 테이블로 되어 있다는 것을 알 수 있다. 그러면 우리가 가져온 데이터에 테이블이 몇개가 있는지 궁금할텐데 len명령어를 통해 확인할 수 있는데 다음과 같이 쓸 수 있다.

# len(테이블명)
len(df)

위의 명령어를 실행하면 현재 가져온 페이지에서 보면 총 3개의 테이블이 있다는 것을 볼 수 있는데, 각 테이블에 어떤 데이터가 있는지 다음 명령어를 통해 확인해보자.

 

각각의 정보를 확인하기 위해서는 pd.read_html(browser.page_source) 뒤에 [] 안에 각각의 번호를 입력해주면 된다. 앞에서 len 명령어를 통해 총 3개의 테이블이 있다는 것을 알았고, 파이썬의 경우 0부터 시작하기 때문에 0, 1, 2의 숫자를 입력하여 확인한다.

 

각각의 결과를 보면 아래 이미지와 같이 나타나는데 우리가 필요한 정보는 두번째 테이블인 1번에 들어있다. 그러면 필요한 정보만 가져올 수 있도록 df를 가져올 때 [1]을 입력해서 가져온다.

 

불필요 데이터 삭제

이제 우리는 1번 테이블에서 가져오면 된다는 것을 알았고 1번 테이블 안에서도 보면 모든 열 또는 모든 행이 NaN이라는 값으로 되어 있는 부분을 볼 수 있다. 

 

다시 네이버 증권 페이지로 돌아가서 확인해보면 행 기준으로 5개씩 종목명 다음에 라인이 그려져 있는 부분을 볼 수 있는데 이 부분이 NaN으로 표시되고 열 기준으로는 토론실 부분이 NaN으로 되어있다.

 

이 부분은 우리에게 필요한 정보가 아니므로 삭제하기로 한다. 삭제하는 방법은 다음과 같다. 앞에서 가져온 df에서 df.dropna라는 명령어를 사용하면 NaN인 부분을 삭제할 수 있다. 

괄호안의 부분은 어떤 경우 삭제할건지에 대해 적용하는 옵션인데 axis 부분에 index를 넣으면 행 기준으로 삭제되고, columns를 넣으면 열 기준으로 삭제된다. 

 

다음으로 how는 NaN이 axis에서 정한 기준으로 모두 NaN인 경우 삭제하려면 all을 입력하고 하나라도 NaN이 있다면 해당 행이나 열을 삭제한다면 any를 입력하면 된다.

# 불필요한 데이터 정제

df.dropna(axis = 'index', how = 'all', inplace = True)
# dropna : 값이 없는 항목 삭제, index : row 기준으로 삭제 옵션
# how = all 줄 전체가 결측일 때 삭제 / any를 넣으면 하나라도 결측이면 삭제
# inplace = True : 결측인 값을 제거한 부분을 실제 데이터 프레임에 적용하는 옵션, 사용하지 않는 경우는 데이터 프레임에 직접 반영되지는 않음

# 컬럼에서 결측만 있는 정보는 삭제
# 네이버 증권에서는 최대 6개까지 선택이 가능하기 때문에 그 이하로 선택한 경우 나머지 칸은 값이 없는 컬럼으로 생성되고 토론실 컬럼이 결측으로 생성됨
df.dropna(axis = 'columns', how = 'all', inplace = True)       # columns는 컬럼 기준으로 적용

 

 

최종 적용코드

그러면 앞에서 적용한 코드들을 이용해서 모든 페이지를 가져오기 위해 for문을 적용한다.  for문에서 range를 이용하면 해당 범위 내에서 반복이 가능한데, for 변수명 in range(시작값, 종료값)으로 사용한다. 이때 종료값은 해당값 이전까지 적용되기 때문에 코스피는 총 45페이지까지 존재하므로 46을 입력해준다.

#########################################################################
# 04. 데이터 가져오기
#########################################################################

p_url = 'https://finance.naver.com/sise/sise_market_sum.naver?sosok=0&page='

#############################################
# (1) 1페이지부터 마지막 페이지까지 필요 테이블 불러오기
for idx in range(1, 46) :            # 마지막 페이지까지 반복, mk_lspg_num 해당 시장 종목 페이지 마지막 번호
    browser.get(p_url + str(idx))                # http 주소는 문자이기 때문에 str을 이용하여 숫자를 문자로 변경해줘야함
    
    # df = pd.read_html(browser.page_source)
    df = pd.read_html(browser.page_source)[1]     # 아래에서 각 테이블 정보를 확인해서 필요한 정보가 들어있는 [1] 테이블의 정보를 가져옴


    
    #############################################
    # (2) 불필요한 데이터 정제
    # 전체가 NaN인 데이터를 보면 네이버증권에서 확인해보면 선이 그려진 부분으로 데이터가 없는 부분임, 소스코드 확인

    df.dropna(axis = 'index', how = 'all', inplace = True)
    # dropna : 값이 없는 항목 삭제, index : row 기준으로 삭제 옵션
    # how = all 줄 전체가 결측일 때 삭제 / any를 넣으면 하나라도 결측이면 삭제
    # inplace = True : 결측인 값을 제거한 부분을 실제 데이터 프레임에 적용하는 옵션, 사용하지 않는 경우는 데이터 프레임에 직접 반영되지는 않음

    # 컬럼에서 결측만 있는 정보는 삭제
    # 네이버 증권에서는 최대 6개까지 선택이 가능하기 때문에 그 이하로 선택한 경우 나머지 칸은 값이 없는 컬럼으로 생성되고 토론실 컬럼이 결측으로 생성됨
    df.dropna(axis = 'columns', how = 'all', inplace = True)       # columns는 컬럼 기준으로 적용

 

다음은 앞에서 작성한 코드를 for문에 적용하면 되는데 들여쓰기를 적용하면 해당 코드가 for문 안에서 동작한다.

728x90

결과를 보면 다음과 같이 나온 것을 볼 수 있는데, 여기서 문제점이 발생했다. 동일한 이름인 df로 for문의 결과값이 생성되어 for문은 정상적으로 1페이지부터 45페이지까지 실행되었지만 맨 마지막 정보인 45페이지의 정보만 df에 들어있는 것을 볼 수 있다.

 

이런 부분이 발생하기 때문에 코드는 하나씩 실행해가면 확인해보는 것이 필요하다. 명령문이 잘못된 것이 아니고 정보를 저장하는 과정에서 발생한 문제이므로 이 부분의 대한 내용은 다음 단계인 데이터를 파일로 저장하는 부분에서 같이 해결해보기로 하겠다.

728x90
반응형

댓글