본문 바로가기
오늘

[파이썬 실전] 네이버 주식 웹페이지 크롤링 프로그램 만들기 [2/2]

by LINK7 2022. 10. 19.
반응형

네이버 주식 웹페이지 크롤링 프로그램 만들기 두 번째 시간입니다.

바로 코드를 보시죠!

 

네이버 주식 웹페이지 크롤링 프로그램 만들기

 

 

3. 데이터 추출

for idx in range(1, 50): # 1이상 50미만 페이지 반복
  # 사전 작업
  browser.get(url + str(idx)) # 각 페이지별로 반복하기 위해서

  # 5. 데이터 추출
  df = pd.read_html(browser.page_source)[1]
  df.dropna(axis='index', how='all', inplace=True)
  df.dropna(axis='columns', how='all', inplace=True)
  if len(df) == 0:
    break

앞서 적용하기 버튼을 눌러 결과가 화면에 표시되었죠?

그럼 이 내용을 파일에 저장하기 전에 지저분한 데이터들을 조금 정리해보겠습니다.

그리고 깨끗해진 데이터들을 파일로 저장하겠습니다.

 

 

for idx in range(1, 50):
  browser.get(url + str(idx))
  • 화면에 표시된 페이지수가 대략 30~40 정도 되더라고요.
  • 그 모든 페이지를 하나씩 경유하면서 데이터를 가져와야 하기에 이렇게 for 반복문으로 시작을 합니다.
  • 1~49까지 하나씩 idx 변수에 담아 browser.get() 함수를 이용해 1 페이지에서 50 페이지를 반복할 겁니다.

 

  df = pd.read_html(browser.page_source)[1]
  • 이제 드디어 padas를 사용합니다.
  • pandas의 read_html() 함수를 이용해 browser의 모든 소스를 가져오는데! 이 read_html() 함수는 페이지의 테이블 형태의 값을 가져옵니다. 현재 화면에 출력된 페이지에는 총 3가지의 테이블 형식의 데이터가 있고요. 그중 2번째가 우리가 목표로 하는 기업들의 정보, 즉, 시가총액, 영업이익, per, pbr... 데이터가 있는 테이블입니다.
  • 그래서 마지막에 [1] 인덱스 값으로 그 테이블을 지정해 준 것입니다.
  • 그렇게 가져온 테이블 데이터를 df 변수에 담습니다.

 

  df.dropna(axis='index', how='all', inplace=True)
  df.dropna(axis='columns', how='all', inplace=True)
  • 가져온 테이블의 데이터 중에는 실제로 값이 존재하지 않는 n/a 값을 가진 셀이 있습니다.
  • 이런 n/a 값을 pandas의 dropna() 함수로 모두 제거하고 제대로 값이 존재하는 데이터만 남겨 이후에 파일로 저장하려고 하는 건데요..
  • 윗줄 코드의 axis='index'는 삭제하려는 방향을 나타냅니다. 가로축이라고 보시면 되고요. how='all' 은 모두 삭제하겠다는 말입니다.
  • 마찬가지로 아랫줄 코드는 삭제하려는 방향은 세로축이고요. 동일하게 모두 삭제하겠다는 말이죠.

 

예를 들자면요. 웹 페이지에 아래와 같은 테이블이 있다고 가정해볼게요.

종목 주가 영업이익 PER PBR ROE 배당률
삼성전자 10,000 5,000 10.5 N/A N/A 5.3
네이버 5,000 500 20.1 0.9 N/A 2.1
카카오 3,000 200 15.8 N/A N/A N/A

pandas의 read.html() 함수는 이 테이블 데이터를 가져오겠죠?

그런데 오른쪽 부분에 N/A 값이 더러 존재하거든요.

이 N/A 값들을 삭제하려면 dropna() 함수를 이용해서 가로축을 기준으로 한 번, 세로축을 기준으로 한 번씩 돌려서

모든 N/A 값을 삭제하는 겁니다. ^^ 

 

 

  if len(df) == 0:
    break
  • 1페이지부터 차례대로 이동하면서 테이블 데이터를 가지고 오는데...
  • 그러다 어느 순간 테이블 데이터가 존재하지 않는 페이지를 만난다는 건?
  • 더 이상 데이터가 존재하지 않는다는 거고, 그 말은 곧 모든 페이지를 다 경유했다는 뜻이죠.
  • 그렇게 되면 break로 for 반복문을 아예 탈출합니다.

 

 

 

4. 파일로 저장

  # 6. 파일로 저장
  f_name = 'kospi_sise.csv'
  if os.path.exists(f_name): # 파일이 있다면? 헤더 제외
    df.to_csv(f_name, encoding='utf-8-sig', index=False, mode='a', header=False)
  else: # 파일이 없다면? 헤더 포함
    df.to_csv(f_name, encoding='utf-8-sig', index=False)
  print(f'{idx} 페이지 완료')

browser.quit() # 브라우저 종료
  • 이제 대망의 파일 저장 부분입니다.
  • 주의하셔야 할 건! 파일 저장하는 이 부분도 앞의 for 반복문의 포함된 코드라는 겁니다.
  • 한 페이지의 테이블 데이터를 가져왔다면 파일에 삽입을 시키고,
  • 그다음 페이지의 테이블 데이터를 가져와서 다시 파일에 삽입을 시키고 하는 작업을 끝 페이지까지 계속 반복해야 하니까 말이죠.

 

 

  f_name = 'kospi_sise.csv'
  • 파일명은 kospi_sise.csv로 정했습니다. f_name이라는 변수에 담고요.

 

 

  if os.path.exists(f_name): # 파일이 있다면? 헤더 제외
    df.to_csv(f_name, encoding='utf-8-sig', index=False, mode='a', header=False)
  else: # 파일이 없다면? 헤더 포함
    df.to_csv(f_name, encoding='utf-8-sig', index=False)
  print(f'{idx} 페이지 완료')
  • 생성된 파일의 제일 상단에는 각 컬럼의 제목이 있어야 하겠죠? 아까 표에서의 종목, 주가, 영업이익, per... 말이에요.
  • 이 컬럼명이 처음에만 생성되고 그다음부터는 안 생겨야 위의 표처럼 정리가 될 거예요.
  • 그래서 파일이 있다면, 즉, 첫 페이지의 데이터를 가져와서 최초에 파일을 만들었으니 그때는 컬럼명 추가 없이 데이터들만 추가하고 바로 header=False이고,
  • 파일이 없다면? 그 말은 첫 데이터이니 파일을 만들어야 한다는 거고 그때는 컬럼명을 맨 윗줄에 넣겠다는 겁니다. header 값을 지정하지 않으면 디폴트가 True 여서 컬럼명을 기재하는 겁니다.
  • 그리고 매 페이지마다 for 반복문을 돌면서 "00 페이지 완료"라는 메시지도 출력되게 했습니다.

 

 

browser.quit() # 브라우저 종료
  • 모든 페이지를 다 경유하게 되면 break 문을 만나 for 문을 빠져나오게 되고요.
  • 그런 즉시 quit() 함수가 실행되어 브라우저가 종료되고 모든 작업이 끝이 납니다!

 

 

 

어떠셨나요?

코드를 글로 설명하려니 많이 헷갈리고 이해하는데 힘드셨을 것 같은데요.

그래도 찬찬히 다시 한번 한 줄 한 줄 보시면서 의미를 파악하려고 조금만 노력하신다면 충분히 이해되실 겁니다.

읽어 주셔서 감사드리고요. 좋은 하루 보내세요~ ^^

 

  

 

반응형

댓글