PythonでEDINETコードリストを取得する

金融界隈で定量的な分析やデータサイエンスをやっている9uantです．
[twitter](https://twitter.com/9uant9)もやってるので，興味ある方はぜひフォローしていただけると！

証券コードとEDINETコードを対応させる表データの取得が面倒だったため，共有したい．

# EDINETコードと証券コード
証券コードは，上場企業の株価情報を取得する際に使用する4桁の数字である．実際には末尾に0を加えて5桁とする．
EDINETコードは，決算情報のデータベースであるEDINET上で企業情報を取得する際に使用するアルファベット＋数字である．

4桁の証券コードをEDINETコードに変換する方法を紹介する．

# EDINETコードリストを取得する
[EDINETタクソミノ及びコードリスト](https://disclosure.edinet-fsa.go.jp/E01EW/BLMainController.jsp?uji.bean=ee.bean.W1E62071.EEW1E62071Bean&uji.verb=W1E62071InitDisplay&TID=W1E62071&PID=W0EZ0001&SESSIONKEY=&lgKbn=2&dflg=0&iflg=0)の下部に，「EDINETコードリスト」がある．今回はPythonを使ってこのcsvデータを取得する．

> chromedriverを事前にダウンロードする必要がある．
> [chromedriverのダウンロードサイト](https://chromedriver.chromium.org/downloads)から，ご自身のchromeのバージョンに合わせてダウンロードされたい．

```python:get_edinet_code_csv.py
import glob
import os
import shutil
import time
from selenium import webdriver
import zipfile

def get_edinet_code_csv(edinetcode_dir):
    '''
    EDINETコードリストのcsvファイルを指定したディレクトリにダウンロードする
    Prameter:
        edinetcode_dir: str
            EDINETコードリストのcsvファイルをダウンロードするディレクトリ
        
    Return:
        edinet_code_list_path: str
            EDINETコードリストのcsvファイルが存在するパス
    '''

    '''
    # ディレクトリが既に存在する場合は，ディレクトリを削除する
    if os.path.exists(edinetcode_dir):
        shutil.rmtree(edinetcode_dir)
    '''

    # seleniumでchromeからzipファイルをダウンロード
    chromeOptions = webdriver.ChromeOptions()
    prefs = {"download.default_directory" : edinetcode_dir} # 保存先のディレクトリの指定
    chromeOptions.add_experimental_option("prefs",prefs)
    chromeOptions.add_argument('--headless') # ブラウザ非表示

    driver = webdriver.Chrome('chromedriverのパス', chrome_options=chromeOptions)
    # EDINETのEDINETコードリストにアクセス
    driver.get('https://disclosure.edinet-fsa.go.jp/E01EW/BLMainController.jsp?uji.bean=ee.bean.W1E62071.EEW1E62071Bean&uji.verb=W1E62071InitDisplay&TID=W1E62071&PID=W0EZ0001&SESSIONKEY=&lgKbn=2&dflg=0&iflg=0')
    driver.execute_script("EEW1E62071EdinetCodeListDownloadAction('lgKbn=2&dflg=0&iflg=0&dispKbn=1');")
    time.sleep(5)
    driver.quit()

    # ダウンロードしたzipファイルのパスを取得
    list_of_files = glob.glob(edinetcode_dir+r'/*') # ワイルドカードを追加
    latest_file = max(list_of_files, key=os.path.getctime) #作成日時が最新のファイルパスを取得

    # zipファイルを同じディレクトリに展開
    zip_f = zipfile.ZipFile(latest_file)
    zip_f.extractall(edinetcode_dir)
    zip_f.close()

    # zipファイルを削除
    os.remove(latest_file)
    
    list_of_files = glob.glob(edinetcode_dir+r'/*') # ワイルドカードを追加
    return max(list_of_files, key=os.path.getctime) # 展開したcsvファイルのパスを返す
```

# 証券コード→EDINETコード
証券コードの配列を，EDINETコードの配列に変換する．

```python:stockcode_to_edinetcode.py
import numpy as np
import pandas as pd

edinet_code_path=get_edinet_code_csv(r"EDINETコードリストのcsvのダウンロード先ディレクトリのパス")

edinet_code_df=pd.read_csv(edinet_code_path,encoding="cp932",header=1,usecols=['ＥＤＩＮＥＴコード', '提出者名', '証券コード'])

def stockcode_to_edinetcode(codes):
    '''
    証券コード（の配列）に対応するEDINETコードの配列を取得する
    Parameter:
        codes: int or float or str or list
            証券コード，またはその配列
    
    Return:
        edinet_codes: list
            引数の順番に対応したEDINETコードの配列
    '''
    
    # 全ての引数を配列に変換
    if type(codes) in (str, int, float):
        codes = [int(codes)]
        
    edinet_codes = []
    
    for code in codes:
        # 4桁の証券コードを5桁に変換
        if len(str(int(code)))==4:
            code = str(int(code))+'0'
            
        tmp = edinet_code_df[edinet_code_df['証券コード']==int(code)]['ＥＤＩＮＥＴコード']
        
        if len(tmp)==0: # 対応するEDINETコードが存在しない場合np.nanを返す
            edinet_codes.append(np.nan)
        else:
            edinet_codes.append(tmp.to_list()[0])
            
    return edinet_codes
```