Coding Is My Life

코딩은 인생

파이썬/파이썬 크롤링

[파이썬 웹 크롤링] 네이버 금융 코스피지수 크롤링

산기대 컴공 2021. 7. 13. 22:12
728x90

파이썬으로 네이버 금융 크롤링

1. 사이트 접속

https://finance.naver.com/sise/sise_index.nhn?code=KPI200 에 접속한 후 

일별 시세표를 확인하다.

 

2. url 구하기

일별 시세 표의 오른쪽 마우스 클릭으로 프레임 소스 코드보기를 클릭한다. 그리고 해당 url에서 앞에 view-source를 제외한 https://finance.naver.com/sise/sise_index_day.nhn?code=KPI200 가 우리가 구하고싶은 표의 url이다. 직접들어가보면 해당표만 있는 것을 볼 수 있다. 여기서 페이지를 이동하면 url뒤에 page=2 이런식으로 표기 되기때문에 https://finance.naver.com/sise/sise_index_day.nhn?code=KPI200&page=2 이런식의 페이지까지 표기된것이 표의 정확한 url이다.

 

3. 해당 url 소스코드 파이썬으로 가져오기

import bs4 #뷰티풀수프를 이용하기 위한 라이브러리
from urllib.request import urlopen # url의 소스코드를 긁어오는 기능의 파이브러리
code = 'KPI200'
page = 1
url = https://finance.naver.com/sise/sise_index_day.nhn?code={code}&page={page}.format(code = code,page = page)
source = urlopen(url).read() # 소스코드 긁어오기
source = bs4.BeatifulSoup(source,'lxml') # 뷰티풀수프의 객체로 바꾸어준다, 뷰티풀수프는 소스코드를 파이썬에서 쉽게 작업하기 위한 객체
print(source.prettify()) # 불러온 소스코드 확인, prettify() = 불러온 데이터를 예쁘게 태그별로 보여준다.

4. 날짜,가격 소스코드에서 찾기

다시 네이버 금융 페이지에서 표에서 아무 날짜에 오른쪽 마우스를 클릭해서 검사를 클릭한다.

그러면 위와 같이 굵은 밑줄로 표시가된다. 이것이 해당 날짜의 태그이다.

여기서 알수있는 사실은 태그는 'td'이고 클래스는 'date'라는 것이다. 이것을 가지고 파이썬에서 찾아보면 다음과 같다.

date = source.find_all('td','date')

find_all은 소스코드에서 찾고자하는 태그들을 찾아 리스트 형식으로 반환한다. 뒤에 인자는 클래스도 써줄 수 있다.

이러면 태그가 td이고 클래스가 date인 태그들이 리스트형식으로 주어진다.

가격도 마찬가지로 데이터를 가지고 오면 다음과 같다.

price = source.find_all('td','number_1')

하지만 가격은 이렇게 가져오면 문제가 발생한다. 리스트를 확인해보면 알겠지만 체결가,등락률,거래량,거래대금까지 리스트에 포함되어있다. 그러므로 체결가는 0,4,8순이므로 후에 작업을 해줘야한다.

 작업은 다음과 같다.

def date_format(d):
  d = str(d).replace('-','.')
  # 년,월,일 분리
  yyyy = int(d.split('.')[0])
  mm = int(d.split('.')[1])
  dd = int(d.split('.')[2])

  this_date = dt.date(yyyy,mm,dd) #date타입으로 바꿈
  return this_date
for n in range(len(date)): 
  if date[n].text.split('.')[0].isdigit(): #isdigit : 알파벳인지 확인, 알파벳이면 True반환
  this_date = date[n].text 
  this_date = date_format(this_date)

  this_close = price[n*4].text # 0,4,8..인덱스 순으로 체결가 값이 들어 있으므로
  this_close = float(this_close) # 소수점이므로 형변환을 해준다.

text는 참고로 태그의 내용을 알려주는 함수이다.

 

여기까지 page1에 대한 날짜와 체결가를 크롤링한 것이다. 이제 마지막 페이지까지 크롤링하는 방법을 알아보자.

 

5. 마지막 페이지 구하기

https://finance.naver.com/sise/sise_index_day.nhn?code=KPI200 에 다시 들어가서 '맨뒤'에 오른쪽 마우스 클릭 후 검사를 클릭해서 소스코드를 본다. 

다음과 같이 맨뒤 페이지가 잡히게된다. 우리가 원하는것은 640이라는 값이다. 이것을 위와 같은 방법으로 뽑아내면 다음과 같다.

paging = source.find_all('table')[1].find_all('tr')[0].find_all('td')[11].find_all('a')[0]
paging = paging['href']
paging = paging.split('&')[1]
paging = paging.split('=')[1]
paging = int(paging)

이러면 paging에 640의 값이 잡히게 된다.

 

1~5의 방법을 종합해서 함수로 연결하면 다음과 같다.

완성된 코드

historical_prices = []
def date_format(d):
  d = str(d).replace('-','.')
  yyyy = int(d.split('.')[0])
  mm = int(d.split('.')[1])
  dd = int(d.split('.')[2])

  this_date = dt.date(yyyy,mm,dd)
  return this_date
def historical_index_naver(index_cd,page_n,last_page):
  naver_index = 'https://finance.naver.com/sise/sise_index_day.nhn?code={code}&page={page}'.format(code = index_cd,page = page_n)
  source = urlopen(naver_index).read()
  source = bs4.BeautifulSoup(source,'lxml')

  date = source.find_all('td','date')
  price = source.find_all('td','number_1')

  for n in range(len(date)):
    if date[n].text.split('.')[0].isdigit(): #isdigit : 알파벳인지 확인, 알파벳이면 True반환
      this_date = date[n].text
      this_date = date_format(this_date)

      this_close = price[n*4].text
      this_close = float(this_close)
      line = []
      line.append(this_date)
      line.append(this_close)
      historical_prices.append(line)

  if last_page == 0:
      last_page = source.find('td','pgRR').find('a')['href']
      last_page = last_page.split('&')[1]
      last_page = last_page.split('=')[1]
      last_page = int(last_page)
  if page_n < last_page:
    page_n = page_n+1
    historical_index_naver(index_cd,page_n,last_page)
historical_index_naver('KPI200',1,0)

 

728x90