INVESTAR / StockAnalysisInPython

456 stars 412 forks source link

DBUpdaterEx.py 에는 ETF 종목이 없더군요. 추가 하려면 어떻게 하면 좋을까요? #54

Open WonSeokChoi-Unicorn opened 3 years ago

WonSeokChoi-Unicorn commented 3 years ago

자동 매매가 나름 buy_etf라는 함수명으로 되어 있을 정도로 etf를 추천해주셨는데

KRX 상장사 목록을 참고하다 보니 ETF 종목들은 없더라구요.

어떻게 하면 가져올 수 있을 지 문의합니다.

INVESTAR commented 3 years ago

DBUpdater는 KRX의 상장사 목록을 가져와서 주식 정보를 DB에 업데이트하는 프로그램이기 때문에 ETF 종목은 다루지 않습니다. ETF 종목까지 업데이트 하도록 하시려면 아래 내용을 참고하셔서 독자님께서 직접 작성하셔야 합니다.

ETF 종목명 및 코드는 네이버 ETF 페이지(https://finance.naver.com/sise/etf.nhn )에서 스크레이핑 할 수 있는데 해당 페이지는 동적인 페이지로 구성되어 있기 때문에 단순히 뷰티풀 수프만 사용해서는 스크레이핑이 불가하고 셀레니움(Selenium)이라는 웹 애플리케이션 테스트 라이브러리를 사용해야 합니다. 자세한 내용은 책의 387 페이지를 참고하시기 바랍니다.

ch08_02_DynamicPageScraping_NaverETF.py

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

# 옵션값 설정
opt = webdriver.ChromeOptions()
opt.add_argument('headless')

# 웹드라이버를 통해 네이버 금융 ETF 페이지에 접속
drv = webdriver.Chrome('C:\myPackage\chromedriver.exe', options=opt)
drv.implicitly_wait(3)
drv.get('https://finance.naver.com/sise/etf.nhn')

# 뷰티풀 수프로 테이블을 스크래핑
bs = BeautifulSoup(drv.page_source, 'lxml')
drv.quit()
table = bs.find_all("table", class_="type_1 type_etf")
df = pd.read_html(str(table), header=0)[0]

# 불필요한 열과 행을 삭제하고 인덱스를 재설정해서 출력
df = df.drop(columns=['Unnamed: 9'])
df = df.dropna()
df.index = range(1, len(df)+1)
print(df)

# 링크 주소에 포함된 종목코드를 추출하여 전체 종목코드와 종목명 출력
etf_td = bs.find_all("td", class_="ctg")
etfs = {}
for td in etf_td:
    s = str(td.a["href"]).split('=')
    code = s[-1]
    etfs[td.a.text] = code
print("etfs :", etfs)
WonSeokChoi-Unicorn commented 3 years ago

힌트 주신 것과 구글링 해서 아래와 같이 구현했습니다.

from pandas.io.json import json_normalize

def read_krx_code(self): """KRX로부터 상장기업 목록 파일을 읽어와서 데이터프레임으로 반환""" url = 'http://kind.krx.co.kr/corpgeneral/corpList.do?method='\ 'download&searchType=13' krx = pd.read_html(url, header=0)[0] krx = krx[['종목코드', '회사명']] krx = krx.rename(columns={'종목코드': 'code', '회사명': 'company'}) krx.code = krx.code.map('{:06d}'.format)

네이버 증권에서 ETF만 가져오기

    etfurl = 'https://finance.naver.com/api/sise/etfItemList.nhn'
    # json으로 가져오기
    json_data = json.loads(requests.get(etfurl).text)
    # dataframe으로 변환하기
    etf_df = json_normalize(json_data['result']['etfItemList'])
    # 종목코드와 회사명만 가져오기
    etf_df = etf_df[['itemcode', 'itemname']]
    # 컬럼명 변경하기
    etf_df = etf_df.rename(columns={'itemcode': 'code', 'itemname': 'company'})

    # 상장자 리스트와 ETF 리스트를 합치기
    stocklist = pd.concat([krx,etf_df])
    return stocklist