ITエンジニアの種籾(たねもみ)

IT技術とか株式投資とか。

EDINETから有価証券報告書をダウンロードする

2020年 07月 27日

目次

EDINET の API を使って、有価証券報告書をダウンロードします。

API

操作ガイドに API の仕様書があります。

API は下記2つで、これらでダウンロードできます。

  1. 書類一覧 API : 提出された書類を把握するための API
  2. 書類取得 API : 提供された書類を取得するための API

書類一覧 API

書類一覧 API の URL は下記です。

https://disclosure.edinet-fsa.go.jp/api/v1/documents.json?date=2019-04-01&type=2

開いてみれば、レスポンスのサンプル見れます。

パラメータの意味は下記です。

  • date : 日付 (YYYY-MM-DD 形式), 過去 5 年の日付が有効。
  • type : 1=メタデータのみ(デフォルト), 2=提出書類一覧及びメタデータ

日付の調査をしてみると、ちょうど5年で最大 1 日幅あるイメージです。 例えば、今日は 2020/7/27 なので、2015/7/27 はダウンロードできますが、2015/7/26 はできなくなっています。 明日 2020/7/28 になれば、2015/7/27 がダメになります。

レスポンスの内容も API 仕様にしっかり書かれているので、結果と仕様書を見れば大丈夫でした。 重要な順にコメントつけておきました。

  • 書類管理番号(docID) : EDINET で唯一。ダウンロードするときに必要。
  • 府令コード(ordinanceCode) : いろんな文書があるので、これで企業情報に絞る。
  • 書類種別コード(docTypeCode) : いろんな文書があるので、これで有価証券報告書に絞る。
  • 提出者 EDINET コード(edinetCode) : EDINET 上での企業のコード。証券のコードとは違う。
  • 提出者証券コード(secCode) : これが証券コードだが、5桁あって最後の桁が0埋めされている。

府令コードは 010 が企業の開示情報で、 書類種別コードは、以下が有価証券報告書のものです。

  • 120 : 有価証券報告書
  • 130 : 訂正有価証券報告書
  • 140 : 四半期報告書
  • 150 : 訂正四半期報告書
  • 160 : 半期報告書
  • 170 : 訂正半期報告書

書類取得 API

書類一覧 API の URL は下記です。

https://disclosure.edinet-fsa.go.jp/api/v1/documents/${書類管理番号}?type=1

パラメータの意味は下記です。

  • type : 1=XBRL, 2=PDF, 3=代替書面・添付文書, 4=英文ファイル

XBRL のファイルをダウンロードしたいので、1 を指定することになります。

実装してみた

API の調査できたので、Python で実装してみました。 関数を作って、期間指定で有価証券報告書だけダウンロードするようにしています。

また、書類一覧 API の json の結果も後から使うかもしれないので、json ファイルで zip と一緒に置いておく仕様にしています。 json の中だけ見ればわかることは json ファイルだけ読めばいいのかなというアイデアです。

import os
import logging
import datetime
import requests
import json
import time

LIMIT_LOOP = 100

EDINET_GET_LIST_URL = "https://disclosure.edinet-fsa.go.jp/api/v1/documents.json?date={param_date}&type=2"
EDINET_GET_ZIP_URL = "https://disclosure.edinet-fsa.go.jp/api/v1/documents/{doc_id}?type=1"
STORE_DIR = "../kabu-data/yufo/{param_date}"
STORE_ZIP_FILE = "{store_dir}/{doc_id}.zip"
STORE_JSON_FILE = "{store_dir}/{doc_id}.json"

def download(start_date, end_date):
    '''
    start_dateからend_dateまでの有価証券報告書をダウロードする
    start_date = datetime.date(2015,7,1)
    end_date = datetime.date(2015,8,1) - datetime.timedelta(days=1)
    '''
    check_date = start_date - datetime.timedelta(days=1)

    for _limit_loop in range(0, LIMIT_LOOP):

        # 次のループの準備と負荷軽減のために1秒は間を開ける
        check_date = check_date + datetime.timedelta(days=1)
        if check_date > end_date:
            break
        time.sleep(1)

        # 日付パラメータ
        param_date = check_date.strftime("%Y-%m-%d")

        # 書類一覧リクエスト
        url = EDINET_GET_LIST_URL.format(param_date=param_date)
        response = requests.get(url)
        logging.info("{url} {status}".format(url=url, status=response.status_code))
        if response.status_code != 200:
            continue # TODO Convert Exception

        # 書類一覧から有価証券報告書関連だけ取り出す
        doc_json = json.loads(response.text)
        if doc_json["metadata"]["status"] != "200":
            print(doc_json)
            continue # TODO Convert Exception
        doc_list = doc_json["results"]

        # 日付ディレクトリ作る
        store_dir = STORE_DIR.format(param_date=param_date)
        if len(doc_list) != 0:
            os.makedirs(store_dir, exist_ok=True)

        # zipをダウンロードする
        for doc in doc_list:
            # 不要なの文書は無視
            if not doc["ordinanceCode"] in ["010"]:
                continue
            if doc["secCode"] is None:
                continue
            if not doc["docTypeCode"] in ["120", "130", "140", "150", "160", "170"]:
                continue
            # 先にjsonを保存
            with open(STORE_JSON_FILE.format(store_dir=store_dir, doc_id=doc["docID"]), 'w') as f:
                json.dump(doc, f, indent=2, ensure_ascii=False)
            # 書類取得リクエスト
            time.sleep(1)
            url = EDINET_GET_ZIP_URL.format(doc_id=doc["docID"])
            response = requests.get(url)
            logging.info("{url} {status}".format(url=url, status=response.status_code))
            # zipを保存
            if response.status_code != 200:
                continue # TODO Convert Exception
            with open(STORE_ZIP_FILE.format(store_dir=store_dir, doc_id=doc["docID"]), 'wb') as f:
                for chunk in response.iter_content(chunk_size=1024):
                    f.write(chunk)

以上です。

広告