본문 바로가기
  • _^**_
무근본 IT 지식 공유/무근본 파이썬(Python)

[무근본 파이썬] 파이썬을 이용한 네이버 증권 정보 크롤링 방법 ! - 왕초보도 이해하는 파이썬 코드예시

by 크리드로얄워터 2023. 4. 20.
반응형

[질문사항]

 

python을 이용한 네이버 증권정보 크롤링 코드
다음 코드를 입력하였을 때 제대로 empty dataframe 이라서, 엑셀에도 아무 내용이 표시되지 않습니다.
혹시 어떻게 고쳐야 할까요?


from selenium import webdriver
from bs4 import BeautifulSoup
import pandas as pd
import time

# 크롬드라이버 경로 설정
driver = webdriver.Chrome('your_chrome_driver_path')

# 종목 코드 입력
code = '005930'

# 재무제표 페이지로 이동
url = f' https://finance.naver.com/item/coinfo.naver?code= {code}&target=finsum_more'
driver.get(url)

# 4년치 재무제표 데이터를 담을 빈 데이터프레임 생성
df_financial = pd.DataFrame()

# 4개 연도의 재무제표 페이지에서 데이터 크롤링
for i in range(4):
    year = driver.find_element_by_id('divMore1').find_elements_by_tag_name('th')[i].text.replace('.', '')
    driver.find_element_by_id('divMore1').find_elements_by_tag_name('th')[i].click()
    time.sleep(1)
    html = driver.page_source
    soup = BeautifulSoup(html, 'html.parser')
    table = soup.select('.gHead01 > tbody')
    table_df = pd.read_html(str(table))[0]
    table_df.columns = table_df.columns.droplevel()  # 중복된 컬럼 레벨 제거
    table_df.columns = [col.replace(' ', '') for col in table_df.columns]  # 컬럼명에 포함된 공백 제거
    table_df.set_index('주요재무정보', inplace=True)  # '주요재무정보' 열을 인덱스로 설정
    table_df = table_df.T  # 행과 열을 전환
    table_df['year'] = year  # 연도 정보를 컬럼으로 추가
    df_financial = pd.concat([df_financial, table_df])  # 크롤링한 데이터를 빈 데이터프레임에 추가
    print(f'{year}년 데이터 크롤링 완료')

# 크롬드라이버 종료
driver.quit()

# 크롤링 결과 출력
print(df_financial)

# 크롤링 결과를 엑셀 파일로 저장
filename = f'{code}_financial.xlsx'
df_financial.to_excel(filename)
print(f'{filename} 파일로 저장 완료')

 

[답변]

 

빈 데이터프레임이 생성된 이유는, 코드에서 find_element_by_tag_name('th') 를 사용하여 재무제표의 연도를 선택할 때, 해당 tag에 연도 정보가 없어서 입니다. 이로 인해 데이터 크롤링 과정에서 table 변수가 빈 값으로 반환되어, 빈 데이터프레임이 생성됩니다.

따라서, 해당 코드를 실행하기 전에 먼저 네이버 증권 사이트에서 해당 종목의 재무제표 페이지를 확인하여, 연도 정보가 어떤 tag에 있는지 확인하시기 바랍니다. 연도 정보가 변경되어 해당 코드에서 사용된 tag가 변경되었을 수도 있습니다.

또한, 크롤링 결과가 출력되지 않는 이유는, 코드에서 table 변수를 선택할 때, '.gHead01 > tbody' 선택자를 사용하여 해당하는 table element를 선택하였는데, 이 선택자가 재무제표 페이지의 table element에 맞지 않을 경우, 데이터를 제대로 가져올 수 없습니다. 이 경우에도 네이버 증권 사이트의 구조가 변경되었을 수 있으니, 구조를 다시 확인하시기 바랍니다.

아래는 재무제표 페이지에서 연도 정보와 데이터를 가져오는 코드입니다. 이 코드를 참고하여 필요한 부분을 수정하시기 바랍니다.

 

# 연도 정보가 있는 tag 선택
year_tags = driver.find_element_by_css_selector('#divMore1 > table > thead > tr > th')

# 4개 연도의 재무제표 페이지에서 데이터 크롤링
for i in range(4):
    # 연도 정보 가져오기
    year = year_tags[i].text.replace('.', '')
    year_tags[i].click()
    time.sleep(1)
    
    # 데이터 가져오기
    html = driver.page_source
    soup = BeautifulSoup(html, 'html.parser')
    table = soup.select('#divMore1 > table > tbody')
    table_df = pd.read_html(str(table))[0]
    table_df.columns = table_df.columns.droplevel()  # 중복된 컬럼 레벨 제거
    table_df.columns = [col.replace(' ', '') for col in table_df.columns]  # 컬럼명에 포함된 공백 제거
    table_df.set_index('주요재무정보', inplace=True)  # '주요재무정보' 열을 인덱스로 설정
    table_df = table_df.T  # 행과 열을 전환
    table_df['year'] = year  # 연도 정보를 컬럼으로 추가
    df_financial = pd.concat([df_financial, table_df])  # 크롤링한 데이터를 빈 데이터프레임에 추가
    print(f'{year}년 데이터 크롤링 완료')

 

 

위 코드를 실행하기 위해서는, 적절한 크롬드라이버와 Selenium 라이브러리가 설치되어 있어야 합니다. 또한, 코드에서 사용된 code 변수에는 해당 종목의 종목코드를 입력해야 합니다.

아래는 전체 코드입니다.

 

from selenium import webdriver
from bs4 import BeautifulSoup
import pandas as pd
import time

# 크롬드라이버 경로 설정
driver = webdriver.Chrome('your_chrome_driver_path')

# 종목 코드 입력
code = '005930'

# 재무제표 페이지로 이동
url = f'https://finance.naver.com/item/coinfo.naver?code={code}&target=finsum_more'
driver.get(url)

# 4년치 재무제표 데이터를 담을 빈 데이터프레임 생성
df_financial = pd.DataFrame()

# 연도 정보가 있는 tag 선택
year_tags = driver.find_element_by_css_selector('#divMore1 > table > thead > tr > th')

# 4개 연도의 재무제표 페이지에서 데이터 크롤링
for i in range(4):
    # 연도 정보 가져오기
    year = year_tags[i].text.replace('.', '')
    year_tags[i].click()
    time.sleep(1)
    
    # 데이터 가져오기
    html = driver.page_source
    soup = BeautifulSoup(html, 'html.parser')
    table = soup.select('#divMore1 > table > tbody')
    table_df = pd.read_html(str(table))[0]
    table_df.columns = table_df.columns.droplevel()  # 중복된 컬럼 레벨 제거
    table_df.columns = [col.replace(' ', '') for col in table_df.columns]  # 컬럼명에 포함된 공백 제거
    table_df.set_index('주요재무정보', inplace=True)  # '주요재무정보' 열을 인덱스로 설정
    table_df = table_df.T  # 행과 열을 전환
    table_df['year'] = year  # 연도 정보를 컬럼으로 추가
    df_financial = pd.concat([df_financial, table_df])  # 크롤링한 데이터를 빈 데이터프레임에 추가
    print(f'{year}년 데이터 크롤링 완료')

# 크롬드라이버 종료
driver.quit()

# 크롤링 결과 출력
print(df_financial)

# 크롤링 결과를 엑셀 파일로 저장
filename = f'{code}_financial.xlsx'
df_financial.to_excel(filename)
print(f'{filename} 파일로 저장 완료')
반응형

댓글