はじめに
前回、EDINETから有価証券報告書を取得するプログラムを作成しました。今回は取得した有価証券報告書に記載されている任意の要素名から値を抽出するプログラムを作成しました。
本プログラムでできること下記となります。
- 取得した有価証券報告書(XBRLファイル)を検索し、その一覧を作成する
- 一覧に記載の有価証券報告書(XBRLファイル)から任意の要素名の値を抽出する
- 抽出した値をCSVファイルに保存する
<生成するCSVファイルの抜粋>
作成したプログラムの説明の前に、EDINETから取得したファイルについて説明します。
EDINETからダウンロードしたzipファイルの構成
最初にEDINETからダウンロードしたzipファイル(XBRLファイル含む)の構成について記載します。XBRLファイルを取得する際は、zip形式で圧縮されたファイルをEDINETからダウンロードします。
ANAホールディングス株式会社のXBRLファイルを含むzipファイルをダウンロードして展開すると、下記のフォルダ構成になっています。
├─ANAホールディングス株式会社
└─XBRL
├─AuditDoc
└─PublicDoc
└─images
<フォルダの概要>
フォルダ名 | フォルダ説明 |
XBRL | ルートフォルダ。同一階層に他のフォルダ、ファイルなどは存在しません。 |
AuditDoc | 監査関連の文書や情報が格納されています。有価証券報告書の監査に関連する文書などが含まれることがあります。このフォルダにもXBRLファイルは存在しているが、有価証券報告書のデータではありません。 |
PublicDoc | 一般の文書や情報を格納しています。主に公的に提供される有価証券報告書のデータを含むXBRLファイルがここに含まれます。 |
images | 文書に関連する画像や図などのマルチメディアコンテンツが格納されていることがあります。報告書内で使用される画像ファイルなどが含まれます。 |
XBRLファイルの内容確認
XBRLファイルには財務情報と企業情報が構造化されて記載されています。
<XBRLファイルの抜粋>
財務情報から「NetSalesSummaryOfBusinessResults(売上高)」の情報を下記に抜粋しました。
<jpcrp_cor:NetSalesSummaryOfBusinessResults contextRef="CurrentYearDuration" decimals="-6" unitRef="JPY">3195537000000</jpcrp_cor:NetSalesSummaryOfBusin>
<抜粋内容の説明>
項目 | 内容 |
jpcrp_cor:NetSalesSummaryOfBusinessResults | 特定の財務情報のタグまたは要素を表します。この場合は「売上高」の要素を指します。この箇所を変更し、XBRLファイル内でさまざまな財務データを示すために使用されます。 |
contextRef=”CurrentYearDuration” | 財務情報のコンテキストを示します。”CurrentYearDuration” は特定の期間(年度)を表し、この “売上高” データが現在の年度に関連していることを示します。コンテキストは、データが報告される期間(Duration)または瞬間(Instant)を指定し、データの正確な意味を提供します。 |
decimals=”-6″ | 報告する数値単位の精度を示します。”-6″ の値は、百万円単位なります。データ値 “3195537000000” は、有価証券報告書の記載では”3195537″となります。 |
unitRef=”JPY” | データの単位を指定します。”JPY” は日本円を表す通貨コードです。 |
3195537000000 | 財務情報の実際の値です。売上高は 3,195,537,000,000 円であることを示しています。 |
企業情報の「FilerNameInJapaneseDEI(提出者名(日本語表記))」の情報を下記に抜粋しました。
<jpdei_cor:FilerNameInJapaneseDEI contextRef="FilingDateInstant">いすゞ自動車株式会社</jpdei_cor:FilerNameInJapaneseDEI>
<抜粋内容の説明>
項目 | 内容 |
jpdei_cor:FilerNameInJapaneseDEI | 企業情報の要素を表します。”FilerNameInJapaneseDEI” は日本語での提出企業名を指します。この箇所を変更し、XBRLファイル内で企業に関連するさまざまな情報を示すために使用されます。 |
contextRef=”FilingDateInstant” | 企業情報のコンテキストを示します。”FilingDateInstant” は提出日時を表し、この企業名データが提出された日時を指します。 |
いすゞ自動車株式会社 | 実際の企業名です。この場合、企業の正式名称は「いすゞ自動車株式会社」であることを示しています。 |
XBRLファイルには売上収益や営業収益、経常収益などの情報を確認することができます。確認することのできる情報の一覧はEDINETが公開している下記リンクからダウンロードできるエクセルファイルで確認することができます。
上記のエクセルファイルには、様式コードごとに何の要素が含まれているのかを、シートごとに分類して記載されています。前回のプログラムで取得したファイルの様式コードは下記となります。
項目名 | 項目ID | コード値 |
府令コード | ordinanceCode | 010 |
様式コード | formCode | 030000 |
「タクソノミ要素リスト 目次」のリンク「企業内容等の開示に関する内閣府令 第三号様式 有価証券報告書 (jpcrp030000-asr)」をクリックすると、シート「9」に移動します。
<「タクソノミ要素リストの目次」の抜粋>
シート「9」の列には「A列:様式ツリー-標準ラベル(日本語)」「B列:詳細ツリー-標準ラベル(日本語)」「C列:冗長ラベル(日本語)」「D列:標準ラベル(英語)」「E列:冗長ラベル(英語)」などが設定されています。
有価証券報告書(XBRLファイル)に記載されている項目を探す場合は「B列:詳細ツリー-標準ラベル(日本語)」で探している項目と一致する行を探します。一致した行の「I列:要素名」を確認して、その要素名で有価証券報告書(XBRLファイル)内を検索することで探したい要素名の値を確認することができます。
有価証券報告書(XBRLファイル)から取得する要素名
本プログラムで、有価証券報告書(XBRLファイル)から取得する財務情報と企業情報の要素名の値は下記となります。取得する要素名の設定を変更することで、取得する要素名の値を変更することができます。
<取得する財務情報>
売上高 | NetSalesSummaryOfBusinessResults |
経常利益 | OrdinaryIncomeLossSummaryOfBusinessResults |
当期純利益 | NetIncomeLossSummaryOfBusinessResults |
純資産額 | NetAssetsSummaryOfBusinessResults |
総資産額 | TotalAssetsSummaryOfBusinessResults |
1株当たり純資産額 | NetAssetsPerShareSummaryOfBusinessResults |
1株当たり配当額 | DividendPaidPerShareSummaryOfBusinessResults |
1株当たり中間配当額 | InterimDividendPaidPerShareSummaryOfBusinessResults |
1株当たり当期純利益 | BasicEarningsLossPerShareSummaryOfBusinessResults |
自己資本比率 | EquityToAssetRatioSummaryOfBusinessResults |
自己資本利益率 | RateOfReturnOnEquitySummaryOfBusinessResults |
株価収益率 | PriceEarningsRatioSummaryOfBusinessResults |
配当性向 | PayoutRatioSummaryOfBusinessResults |
株主総利回り | TotalShareholderReturn |
<取得する企業情報>
提出者名(日本語表記) | FilerNameInJapaneseDEI |
EDINETコード | EDINETCodeDEI |
EDINET証券コード | SecurityCodeDEI |
決算日 | CurrentPeriodEndDateDEI |
プログラムの内容
作成したプログラムは下記となります。
# 有価証券報告書(XBRLファイル)からデータを抽出するプログラム
# 事前準備
# - EdinetReportFetcher.pyでXBRLファイルを取得しておいてください。
# - pip installでtqdmをPython実行環境にインストールしておいてください。
# - XBRLファイルのパスをroot_folderに設定してください。
# - 抽出したデータを保存するファイルをoutput_fileに設定してください。
# 実行する方法
# - pythonの実行環境で下記を実行してください。引数はありません。
# python XBRLDataExtractor.py
import os
import pandas as pd
from tqdm import tqdm
import xml.etree.ElementTree as ET
class XBRLProcessor:
"""
XBRLファイルから企業情報を抽出し、CSVファイルに保存するためのクラスです。
このクラスは、指定されたフォルダ内のXBRLファイルを探索し、提出本文書から企業情報と財務情報を抽出します。
抽出した情報はCSVファイルに保存されます。
"""
def __init__(self, root_folder, target_extension, exclude_keyword, list_jpcrp_cor_tag, list_jpdei_cor_tag, output_file):
"""
:param root_folder: str
XBRLファイルを探索するルートフォルダのパス
:param target_extension: str
探索するファイルの拡張子
:param exclude_keyword: str or None
除外するファイルパスに含まれるキーワード(不要ない場合はNone)
:param list_jpcrp_cor_tag: list
抽出する財務情報のタグのリスト(提出本文書)
:param list_jpdei_cor_tag: list
抽出する企業情報のタグのリスト(企業情報開示)
:param output_file: str
抽出した情報を保存するCSVファイルのパス
"""
self.root_folder = root_folder
self.target_extension = target_extension
self.exclude_keyword = exclude_keyword
self.list_jpcrp_cor_tag = list_jpcrp_cor_tag
self.list_jpdei_cor_tag = list_jpdei_cor_tag
self.output_file = output_file
self.df_companies_info = pd.DataFrame()
def search_files(self):
"""
指定されたフォルダ内を、指定した拡張子のファイルを再帰的に検索してファイルパスのリストを取得します。
このメソッドは、指定したフォルダ内を再帰的に探索し、指定された拡張子のファイルを特定し、
ファイルパスのリストを作成します。また、除外キーワードが指定されている場合は、それを含むファイルパスは除外されます。
:return: list
検索対象の拡張子に一致したファイルのパスのリスト
"""
matched_files = []
for root, _, files in os.walk(self.root_folder):
for file in files:
if (file.endswith(self.target_extension) and
(self.exclude_keyword is None or self.exclude_keyword not in os.path.join(root, file))):
matched_files.append(os.path.join(root, file))
return matched_files
def parse_xbrl_file(self, xbrl_path):
"""
指定されたXBRLファイルから企業情報と財務情報を抽出し、データフレームに格納します。
このメソッドは、XBRLファイルを解析し、特定のタグ情報を抽出してデータフレームに整形します。
タグ情報は提出本文書に関する情報(jpcrpとjpdei)で構成され、データフレーム形式で戻されます。
:param xbrl_path: str
解析対象のXBRLファイルのパス
:return: pandas.DataFrame
XBRLファイルから抽出したタグ情報が整形されたデータフレーム
"""
dict_jpcrp_cor_parm = {}
dict_jpdei_cor_parm = {}
tree = ET.parse(xbrl_path)
root = tree.getroot()
for elem in root:
for tag_name in self.list_jpcrp_cor_tag:
if tag_name in elem.tag:
dict_jpcrp_cor_parm[f"{tag_name}_{elem.get('contextRef')}"] = elem.text
for tag_name in self.list_jpdei_cor_tag:
if tag_name in elem.tag:
dict_jpdei_cor_parm[tag_name] = elem.text
df_jpdei_cor_parm = pd.DataFrame(list(dict_jpdei_cor_parm.items()),
columns=["Tag_ContextRef",
dict_jpdei_cor_parm.get('FilerNameInJapaneseDEI', '')])
df_jpcrp_cor_parm = pd.DataFrame(list(dict_jpcrp_cor_parm.items()),
columns=['Tag_ContextRef',
dict_jpdei_cor_parm.get('FilerNameInJapaneseDEI', '')])
df_company_info = pd.concat([df_jpdei_cor_parm, df_jpcrp_cor_parm])
df_company_info = df_company_info.set_index('Tag_ContextRef')
return df_company_info
def process_xbrl_files(self):
"""
XBRLファイルを処理し、指定したフォルダ内から対象の情報を抽出します。
このメソッドは、指定されたフォルダ内を再帰的に検索し、対象の拡張子を持つファイルから企業情報を抽出します。
抽出した情報は内部のデータフレームに保存されます。
"""
found_files = self.search_files()
for xbrl_path in tqdm(found_files):
df_company_info = self.parse_xbrl_file(xbrl_path)
self.df_companies_info = pd.concat([self.df_companies_info, df_company_info], axis=1)
def save_to_csv(self):
"""
抽出した情報をCSVファイルでoutput_fileに保存します。
"""
self.df_companies_info.to_csv(self.output_file, encoding='cp932')
if __name__ == "__main__":
# XBRLファイルの提出本文書から取得する財務情報のタグを設定
list_jpcrp_cor_tag = [
'NetSalesSummaryOfBusinessResults', # 売上高
'OrdinaryIncomeLossSummaryOfBusinessResults', # 経常利益
'NetIncomeLossSummaryOfBusinessResults', # 当期純利益
'NetAssetsSummaryOfBusinessResults', # 純資産額
'TotalAssetsSummaryOfBusinessResults', # 総資産額
'NetAssetsPerShareSummaryOfBusinessResults', # 1株当たり純資産額
'DividendPaidPerShareSummaryOfBusinessResults', # 1株当たり配当額
'InterimDividendPaidPerShareSummaryOfBusinessResults', # 1株当たり中間配当額
'BasicEarningsLossPerShareSummaryOfBusinessResults', # 1株当たり当期純利益
'EquityToAssetRatioSummaryOfBusinessResults', # 自己資本比率
'RateOfReturnOnEquitySummaryOfBusinessResults', # 自己資本利益率
'PriceEarningsRatioSummaryOfBusinessResults', # 株価収益率
'PayoutRatioSummaryOfBusinessResults', # 配当性向
'TotalShareholderReturn' # 株主総利回り
]
# XBRLファイルの提出本文書から取得する企業情報のタグを設定
list_jpdei_cor_tag = [
'FilerNameInJapaneseDEI', # 企業名
'EDINETCodeDEI', # EDINETコード
'SecurityCodeDEI', # EDINET証券コード
'CurrentPeriodEndDateDEI' # 決算日
]
root_folder = 'C:/temp/data/zip/20231006/extract'
target_extension = '.xbrl'
exclude_keyword = 'AuditDoc'
output_file = '企業財務情報一覧.csv'
xbrl_processor = XBRLProcessor(root_folder, target_extension, exclude_keyword,
list_jpcrp_cor_tag, list_jpdei_cor_tag, output_file)
xbrl_processor.process_xbrl_files()
xbrl_processor.save_to_csv()
プログラムの補足
プログラム内で用意したメソッドについて補足します。
parse_xbrl_file メソッド
- XBRLファイルの解析にはPythonの標準ライブラリであるxml.etree.ElementTreeを使用しています。
- XMLファイルの解析には、BeautifulSoupやlxmlなどを用いて行うこともできます。本プログラムでは、一般的に広く使用されているxml.etree.ElementTreeを用いました。
- このメソッドは、XBRLファイルごとに処理を実行するので、1回の呼び出しで1企業の情報を取得することになります。
process_xbrl_files メソッド
- parse_xbrl_file メソッドを呼び出したあと、parse_xbrl_file メソッドで取得した企業情報のデータフレーム同士を結合し、複数の企業情報を1つにまとめたデータフレームを作成します。
取得する要素を増やす方法
- 取得する財務情報を変更する場合は「list_jpcrp_cor_tag」のリストを編集します。
- 取得する企業情報を変更する場合は「list_jpdei_cor_tag」のリストを編集します。
- 財務情報、企業情報の要素は「タクソノミ要素リストの目次」で確認できます。
プログラムの実行環境
実行環境の主なパッケージのバージョンは下記となります。
パッケージ | バージョン |
python | 3.10.9 |
pandas | 1.5.2 |
プログラム実行前の準備
プログラムの実行環境に合わせて下記を実施する必要があります。
パッケージの追加
プログラムの実行にはtqdmのパッケージが必要です。実行環境にtqdmをインストールしてください。
pip install tqdm
設定の更新
プログラムの実行前に、下記設定を実行環境に合わせて更新しておいてください。
- root_folder
EDINETからダウンロードした有価証券報告書のzipを展開したフォルダのパスを指定します。
前回のプログラムを実行し、zipが展開されたフォルダのパスを指定します。 - output_file
抽出したデータを保存するCSVファイル名を指定します。
ファイル名は任意となります。
掲載したプログラムの148行目と151行目に該当します。
プログラムの実行方法
- プログラムのコードを「任意のファイル名.py」で保存してください。
ここでは「XBRLDataExtractor.py」としています。 - Pythonの実行環境を開いてください。
- 下記のコマンドで実行します。
> python XBRLDataExtractor.py
プログラムの実行結果
プログラムを実行すると「output_file」で指定したファイルパスに取得した企業情報を保存します。
次回、試したいこと
取得した企業情報から、高配当の条件を満たす銘柄を抽出するプログラムを作成します。以前、同様の処理を行うプログラムを作成したので、そこまで時間は掛からない想定でいます。レポート生成プログラムの作成も着手します。
コメント