[FinDA] 거래소(KRX) 상장법인목록 크롤링 및 MySQL DB update


1. 상장법인목록

http://kind.krx.co.kr/corpgeneral/corpList.do?method=loadInitPage

다운로드한 파일의 확장자가 xls 이지만 열어보면 html 이다.

img

크롬 개발자도구를 통해 EXCEL 버튼 선택시 웹브라우저의 동작을 확인한다.

검사 - Network - Name (corpList.do) - Headers

  • request url : http://kind.krx.co.kr/corpgeneral/corpList.do
  • Form Data 항목에서 요청에 사용된 키와 값을 확인

img

import pandas as pd
import numpy as np
import requests
from bs4 import BeautifulSoup
from io import BytesIO
def stock_master():
    url = 'http://kind.krx.co.kr/corpgeneral/corpList.do'
    data = {
        'method':'download',
        'orderMode':'1',           # 정렬컬럼
        'orderStat':'D',           # 정렬 내림차순
        'searchType':'13',         # 검색유형: 상장법인
        'fiscalYearEnd':'all',     # 결산월: 전체
        'location':'all',          # 지역: 전체
    }

    r = requests.post(url, data=data)
    f = BytesIO(r.content)
    dfs = pd.read_html(f, header=0, parse_dates=['상장일'])
    df = dfs[0].copy()

    # 숫자를 앞자리가 0인 6자리 문자열로 변환
    df['종목코드'] = df['종목코드'].astype(np.str)   
    df['종목코드'] = df['종목코드'].str.zfill(6)
    return df
df_master = stock_master()
df_master.head()
회사명 종목코드 업종 주요제품 상장일 결산월 대표자명 홈페이지 지역
0 BYC 001460 봉제의복 제조업 메리야스,란제리 제조,도매/건축공사/부동산 임대,분양,공급 1975-06-02 12월 유 중 화 http://www.byc.co.kr 서울특별시
1 CJ씨푸드 011150 기타 식품 제조업 수산물(어묵,맛살)가공품 도매,원양수산업,수출입 1988-11-26 12월 유병철, 강신호(각자대표) http://www.cjseafood.net 경기도
2 DRB동일 004840 회사본부, 지주회사 및 경영컨설팅 서비스업 고무벨트(V벨트,콘베이어벨트,평벨트),프라스틱제품 제조,판매 1976-05-21 12월 박진삼 http://drbworld.com 부산광역시
3 DSR제강 069730 1차 철강 제조업 와이어로프,각종 경강선,철선제품,PC강선,아연도 강연선 제조 2003-01-28 12월 홍하종 http://www.dsrcorp.com 전라남도
4 GS건설 006360 건물 건설업 토목공사,건축공사,주택공사,산업플랜트공사,리모델링공사,시설물유지관리공사/산업설비설계... 1981-08-03 12월 허창수, 임병용(각자 대표이사) http://www.gsconst.co.kr/ 서울특별시
df = df_master.loc[:, ['회사명', '종목코드', '업종', '상장일', '결산월']]
df.head()
회사명 종목코드 업종 상장일 결산월
0 BYC 001460 봉제의복 제조업 1975-06-02 12월
1 CJ씨푸드 011150 기타 식품 제조업 1988-11-26 12월
2 DRB동일 004840 회사본부, 지주회사 및 경영컨설팅 서비스업 1976-05-21 12월
3 DSR제강 069730 1차 철강 제조업 2003-01-28 12월
4 GS건설 006360 건물 건설업 1981-08-03 12월

2. 거래소(KRX) 전체 종목코드 크롤링 (시가총액순위)

트래픽 분석

시장정보 - 주식 - 순위정보 - 시가총액 상하위 - CSV 선택

시가총액순 종목리스트는 다음과 같이 두 단계에 걸쳐 진행된다.

  1. http://marketdata.krx.co.kr/contents/COM/GenerateOTP.jspx
  2. http://file.krx.co.kr/download.jspx : GenerateOTP.jspx를 통해 리턴받은 값을 입력으로 사용한다.

데이터 가져오기

import pandas as pd
import numpy as np
import requests
from io import BytesIO
from datetime import datetime
def stock_master_price(date=None):
    if date == None:
        date = datetime.today().strftime('%Y%m%d')   # 오늘 날짜

    # STEP 01: Generate OTP
    gen_otp_url = 'http://marketdata.krx.co.kr/contents/COM/GenerateOTP.jspx'
    gen_otp_data = {
        'name':'fileDown',
        'filetype':'xls',
        'url':'MKD/04/0404/04040200/mkd04040200_01',
        'market_gubun':'ALL',                          #시장구분: ALL=전체
        'indx_ind_cd':'',
        'sect_tp_cd':'',
        'schdate': date,
        'pagePath':'/contents/MKD/04/0404/04040200/MKD04040200.jsp',
    }
    
    r = requests.post(gen_otp_url, gen_otp_data)
    code = r.content  # 리턴받은 값을 아래 요청의 입력으로 사용.
    
    # STEP 02: download
    down_url = 'http://file.krx.co.kr/download.jspx'
    down_data = {
        'code': code,
    }
    
    r = requests.post(down_url, down_data)
    df = pd.read_excel(BytesIO(r.content), header=0, thousands=',')
    return df
df = stock_master_price()
df.head()
종목코드 종목명 현재가 대비 등락률 거래량 거래대금 시가총액 시가총액비중(%) 상장주식수(천주) 외국인 보유주식수 외국인 지분율(%)
0 005930 삼성전자 2090000 -17000 -0.8 69044 144463049000 294019814330000 18.35 140679337 NaN NaN
1 000660 SK하이닉스 49300 -1000 -2.0 1449682 71990011200 35890516594500 2.24 728002365 NaN NaN
2 005935 삼성전자우 1615000 -25000 -1.5 17531 28297084000 33129184605000 2.07 20513427 NaN NaN
3 005380 현대차 149000 -1000 -0.7 187065 27902233000 32821195371000 2.05 220276479 NaN NaN
4 015760 한국전력 45650 -450 -1.0 439486 20161042650 29305660115050 1.83 641964077 NaN NaN
date = datetime(2017, 3, 3).strftime('%Y%m%d')
df = stock_master_price(date)
df.head()
종목코드 종목명 현재가 대비 등락률 거래량 거래대금 시가총액 시가총액비중(%) 상장주식수(천주) 외국인 보유주식수 외국인 지분율(%)
0 005930 삼성전자 1981000 -5000 -0.2 254174 500689858000 278685766597000 18.07 140679337 71175695 50.59
1 000660 SK하이닉스 47100 -600 -1.3 3937032 186640393450 34288911391500 2.22 728002365 358720683 49.27
2 005935 삼성전자우 1545000 -22000 -1.4 60571 93097539000 31693244715000 2.05 20513427 15857741 77.30
3 005380 현대차 142000 -6500 -4.4 774281 110458431000 31279260018000 2.03 220276479 98462189 44.70
4 015760 한국전력 42950 -200 -0.5 1166862 49900115200 27572357107150 1.79 641964077 199597043 31.09
len(df)
2253

3. 거래소(KRX) 상장회사목록 크롤링 & DB update

트래픽 분석

시장정보 - 주식 - 상장현황 - 상장회사검색 - CSV 선택

두 단계에 걸쳐 진행됨.

  1. http://marketdata.krx.co.kr/contents/COM/GenerateOTP.jspx
  2. http://file.krx.co.kr/download.jspx : GenerateOTP.jspx를 통해 리턴받은 값을 입력으로 사용한다.

데이터 가져오기

import pandas as pd
import numpy as np
import requests
import io
def get_krx_stock_master():
    # STEP 01: Generate OTP
    gen_otp_url = 'http://marketdata.krx.co.kr/contents/COM/GenerateOTP.jspx'
    gen_otp_data = {
        'name':'fileDown',
        'filetype':'xls',
        'url':'MKD/04/0406/04060100/mkd04060100_01',
        'market_gubun':'ALL',                          # ALL:전체
        'isu_cdnm':'전체',
        'sort_type':'A',                               # 정렬 : A 기업명
        'std_ind_cd':'01',
        'cpt':'1',
        'in_cpt':'',
        'in_cpt2':'',
        'pagePath':'/contents/MKD/04/0406/04060100/MKD04060100.jsp',
    }  # Query String Parameters

    r = requests.post(gen_otp_url, gen_otp_data)
    code = r.content

    # STEP 02: download
    down_url = 'http://file.krx.co.kr/download.jspx'
    down_data = {
        'code': code,
    }

    r = requests.post(down_url, down_data)
    f = io.BytesIO(r.content)
    
    usecols = ['종목코드', '기업명', '업종코드', '업종']
    df = pd.read_excel(f, converters={'종목코드': str, '업종코드': str}, usecols=usecols)
    df.columns = ['code', 'name', 'sector_code', 'sector']
    return df
df_master = get_krx_stock_master()
df_master.head()
code name sector_code sector
0 060310 3S 032602 전자부품 제조업
1 095570 AJ네트웍스 126903 산업용 기계 및 장비 임대업
2 068400 AJ렌터카 126901 운송장비 임대업
3 006840 AK홀딩스 137105 회사본부, 지주회사 및 경영컨설팅 서비스업
4 054620 AP시스템 032902 특수 목적용 기계 제조업

Database Update

import mysql.connector
from sqlalchemy import create_engine
con_str = 'mysql+mysqlconnector://woosa7:finda***@localhost/findb'
engine = create_engine(con_str, echo=False)
insert_update_sql = """
    insert into stock_master (code, name, sector_code, sector) 
    values (%s,%s,%s,%s)
    on duplicate key update
        code=values(code),
        name=values(name),
        sector_code=values(sector_code),
        sector=values(sector)
"""
for ix, r in df_master.iterrows():
    engine.execute(insert_update_sql, (r['code'], r['name'], r['sector_code'], r['sector']))
    print(r['code'], r['name'])
060310 3S
095570 AJ네트웍스
068400 AJ렌터카
006840 AK홀딩스
054620 AP시스템
211270 AP위성
027410 BGF리테일
138930 BNK금융지주
001460 BYC
032040 C&S자산관리
001040 CJ
......
010240 흥국
189980 흥국에프엔비
000540 흥국화재
003280 흥아해운
037440 희림