🎧

【Python】EDINET APIから取得した有価証券報告書のテキストデータと財務データを保存【Google Colab】

2022/11/13に公開

まとめると

つぎの流れでやっていきます。

  • ライブラリのインポート
  • 有価証券報告書のdocIDを取得
  • 有価証券報告書が入ったzipファイルを取得
  • zipファイルを解凍
  • XBRLファイルからテキストデータと財務データを取得
  • 取得したデータをGoogle Driveに保存

作成にあたっては次の記事を参考にしました。とても役立つ内容をありがとうございます!
https://zenn.dev/robes/articles/4ab5a7f992000d
こちらの記事からの+として、財務データも取得できるようにして、それをGoogle Drive上に保存した、という記事です。

ライブラリのインポート

import datetime
import requests
import pandas as pd
import zipfile
from tqdm import tqdm_notebook as tqdm
import glob
from bs4 import BeautifulSoup
!pip install edinet_xbrl
from edinet_xbrl.edinet_xbrl_parser import EdinetXbrlParser

有価証券報告書のdocIDを取得

今回は、2022年3月が決算月になっている企業の有価証券報告書のdocIDを取得してみます。

start_date = datetime.date(2022, 3, 31)
end_date = datetime.date(2022, 6, 30)
#決算後3ヶ月以内に有報を提出しなければならない規則から、end_dateを2022/06/30に指定

period = end_date - start_date
period = int(period.days)
day_list = []
for d in range(period):
    day = start_date + datetime.timedelta(days=d)
    day_list.append(day)
    
day_list.append(end_date)
#結果を格納するための空のリストを用意
report_list =[]
#日付リストの期間に提出された書類のメタデータを取得してjson形式に変換
for day in day_list:
    url = "https://disclosure.edinet-fsa.go.jp/api/v1/documents.json"
    params = {"date": day, "type": 2}
    res = requests.get(url, params=params)
    json_data = res.json()

    for num in range(len(json_data["results"])):
        ordinance_code = json_data["results"][num]["ordinanceCode"]
        form_code = json_data["results"][num]["formCode"]
        sec_code = json_data["results"][num]["secCode"]
        
	#ordinance_code=010かつform_code=030000が有価証券報告書
        if ordinance_code == "010" and  form_code =="030000":
            company_name=json_data["results"][num]["filerName"]
            edi={ '会社名':company_name,
                        '書類名':json_data["results"][num]["docDescription"],
                        'docID':json_data["results"][num]["docID"],
                        '証券コード':json_data["results"][num]["secCode"],
                        '開始時期':json_data["results"][num]["periodStart"],
                        '終了時期':json_data["results"][num]["periodEnd"],
                        '日付': day,
                        'XBRL':json_data["results"][num]["xbrlFlag"]}
            report_list.append(edi)
df = pd.DataFrame(report_list)
docid_list = df['docID'].tolist()

これで対象企業(今回であれば決算月が2022年3月)の有価証券報告書のdocIDのリストが取得できました。

有価証券報告書が入ったzipファイルを取得

filename_list = []

for docid in tqdm(docid_list):
    # 書類取得APIのエンドポイント
    url = "https://disclosure.edinet-fsa.go.jp/api/v1/documents/" + docid
    #print(url)
    
    # 書類取得APIのリクエストパラメータ
    params = {
        "type" : 1}
        
    # 出力ファイル名
    filename_list.append(docid + ".zip")

    # 書類取得APIの呼び出し
    res = requests.get(url, params=params, verify=False)
    # ファイルへ出力
    # print(res.status_code)
    if res.status_code == 200:
        with open(docid+".zip", 'wb') as f:
            for chunk in res.iter_content(chunk_size=1024):
                f.write(chunk)

zipファイルを解凍

for i, docid in enumerate(docid_list):
    print(filename_list[i])
    if zipfile.is_zipfile(filename_list[i]) == True:
      with zipfile.ZipFile(filename_list[i]) as zip_f:
        zip_f.extractall(docid)
    if zipfile.is_zipfile(filename_list[i]) == False: #エラー回避
      print(filename_list[i] + " is not a Zip File")
      docid_list.remove(docid)

XBRLファイルからテキストデータと財務データを取得

ついにここまできました!もう少し💪

#インスタンス化
parser = EdinetXbrlParser()

テキストデータ・財務データを格納するための空のデータフレームをあらかじめ用意しておきます。ここでカラム名をdocIDと取得したいデータにしておきます。

content = pd.DataFrame(columns=['docID','経営方針','事業等のリスク','経営者の分析', '総資産','経常利益', '売上高'])
for _docID in tqdm(docid_list):
    #xbrlファイルのパスを指定
    xbrl_path = '/content/' + _docID + '/XBRL/PublicDoc/*.xbrl'
    print(i)
    xbrl_path = glob.glob(xbrl_path)[0]
    print(xbrl_path)
    edinet_xbrl_object = parser.parse_file(xbrl_path)
    
    #タクソノミ要素となるkeyとcontext_refを指定
    #経営方針、経営環境および対処すべき課題等
    key_houshin= 'jpcrp_cor:BusinessPolicyBusinessEnvironmentIssuesToAddressEtcTextBlock'
    
    #事業等のリスク
    key_risk ='jpcrp_cor:BusinessRisksTextBlock'

    #経営者による財政状態、経営成績及びキャッシュ・フローの状況の分析
    key_management ='jpcrp_cor:ManagementAnalysisOfFinancialPositionOperatingResultsAndCashFlowsTextBlock'

    #総資産
    key_assets = 'jpcrp_cor:TotalAssetsSummaryOfBusinessResults'

    #経常利益
    key_ordinaryincome = 'jppfs_cor:OrdinaryIncome'

    #売上高
    key_netsales = 'jpcrp_cor:NetSalesSummaryOfBusinessResults'

    #context_refを定義
    context_ref_1 = 'FilingDateInstant'
    context_ref_2 = 'CurrentYearInstant'
    context_ref_3 = 'CurrentYearDuration'
     
    #例外処理
    try:
        data_houshin = edinet_xbrl_object.get_data_by_context_ref(key_houshin, context_ref_1).get_value()
        soup_houshin = BeautifulSoup(data_houshin,'html.parser').get_text(strip=True)
        
        data_risk = edinet_xbrl_object.get_data_by_context_ref(key_risk, context_ref_1).get_value()
        soup_risk = BeautifulSoup(data_risk,'html.parser').get_text(strip=True)

        data_management = edinet_xbrl_object.get_data_by_context_ref(key_management, context_ref_1).get_value()
        soup_management = BeautifulSoup(data_management,'html.parser').get_text(strip=True)

        data_assets = edinet_xbrl_object.get_data_by_context_ref(key_assets, context_ref_2).get_value()
        
        data_ordinaryincome = edinet_xbrl_object.get_data_by_context_ref(key_ordinaryincome, context_ref_3).get_value()
        
        data_netsales = edinet_xbrl_object.get_data_by_context_ref(key_netsales, context_ref_3).get_value()
        
        tmp_se = pd.DataFrame([[_docID], [soup_houshin],[soup_risk],[soup_management],[data_assets],[data_ordinaryincome], [data_netsales]], index=content.columns).T
        content = content.append(tmp_se)
    
    except AttributeError as e:
        print(e)


#数値型に変換
content['総資産'] = content['総資産'].astype(int)
content['経常利益'] = content['経常利益'].astype(int)
content['売上高'] = content['売上高'].astype(int)
content

これでデータが取れたはずです!🌸

取得したデータをGoogle Driveに保存

取得できたデータをcsvにしてGoogle Driveに保存します。
以下のコードを実行するとポップアップが出てくるので、手動でアクセスを許可します。
今回はマイドライブ直下に保存します。

#ドライブ設定
PATH_GMOUNT='/content/gdrive'
PATH_MYDRIVE=PATH_GMOUNT+'/My Drive'
#Google Driveマウント
from google.colab import drive
drive.mount(PATH_GMOUNT)

保存名も指定できます。

content.to_csv(f'{PATH_MYDRIVE}/content.csv', index=False)
!ls -lrt '{PATH_MYDRIVE}'

おわり

これでテキスト分析、財務分析の準備が整いました!
※XBRLファイルからデータを取得する際、業種などでタクソノミが異なるという点を反映できていないので、取得できていないデータが抜け落ちている可能性があります、、その点の改善が課題です。
https://qiita.com/XBRLJapan/items/14c5dea59d36c813f010
こちらの記事が参考になるかも、、?

少しでもこの記事が役立っていたら嬉しいです🐱
何かエラーなどありましたらコメントお待ちしています!

Discussion