はじめに
結構前にこんな記事を書いたんですが、肝心かなめの「決算短信のXBRLからデータを取得する」部分を一切書いていませんでした。申し訳ないです。なので今回はそこら辺をちゃんと書いてみようかなと思い記事を出すことにしました。
決算短信XBRLの取得先としては
- TDnet 適時開示情報サービス
- 東証上場会社情報サービス
あたりが有力でしょうか。
今回はとりあえずTDnetから決算短信のXBRLをダウンロードするところまでをやってみます。
ご注意いただきたいのですが、決算短信の情報を取得するだけならJPXが提供しているJ-Quants APIを利用するのが一番手っ取り早いです。しかも、結構安いのでこちらの方をお勧めします。
ここからJ-QuantsAPIの公式ページに飛べます。過去2年間分のデータで良いなら無料で利用可能です。1年間ごとに登録しなおしになりますが、とりあえずやってみたいという方は是非使ってみてほしいです。
ここではJ-QuantsAPIでとれるデータでは満足できない、自分でコードを書いていろいろやりたいという珍しい方向けにこの記事を書いています。
TDnetから決算短信のXBRLをダウンロードする
方針
以下はTDnetの適時開示一覧ページです。例では2024年2月16日のものを表示しています。
公開日を選択することで1カ月以内の特定の日に開示された開示情報を見ることが出来ます。ページのソースを読んでみると、公開日の選択を変更するとjavascriptが動作し、iframeタグが表示するhtmlソースが切り替わるという作りになっているようです。
iframeタグが表示するhtmlソースはもちろんTDnetのサーバ上に存在し「https://www.release.tdnet.info/inbs/I_list_001_20240216.html」のようなURLとなっています。ファイル名はl_list_ページ番号_年月日.htmlのように決まっています。
したがって、データを取得するには日付とページ番号からURLを生成し、GETリクエストを送って取得できたページソースから情報を抜き出せばいいです。ページ番号は1から始め、サーバがNot Foundを返すまで繰り返すのが一番簡単だと思います。また、以下の例のように開示がない日時の場合は開示された情報がないと表示されるのでこれについても考慮する必要があります。
ここでは開示の
- 開示時刻
- 銘柄コード
- 会社名
- 表題
- XBRLのパス
- 上場取引所
- 更新履歴
を取得します。
あとは表題に「決算短信」というワードを含むものだけを抜き出し、XBRLをダウンロードすればよいです。
実装
ページソースを取得し、方針を立てる
とりあえず、requestsライブラリを使ってサーバにGETリクエストを送り、ページソースを取得します。ここでは綺麗な形でページソースを読みたいのでhtmlパーサーを使ってページ構造を取得したうえでページソースを表示しています。
import requests from bs4 import BeautifulSoup r = requests.get('https://www.release.tdnet.info/inbs/I_list_001_20240216.html') soup = BeautifulSoup(r.content, 'html.parser') r.close() print(soup.prettify())
実行結果
<!DOCTYPE html> <html> <head> <title> 適時開示情報閲覧サービス - 開示情報一覧 </title> <meta charset="utf-8" content="text/html" http-equiv="content-type"/> <meta content="noindex,nofollow" name="robots"/> <meta content="no-cache" http-equiv="Pragma"/> <meta content="no-cache" http-equiv="Cache-Control"/> (以下略)
ページソースのうち重要な部分だけを抜き出しました。
<table align="left" border="0" cellpadding="3" cellspacing="0" id="main-list-table"> <tr> <td class="oddnew-L kjTime" nowrap=""> 23:55 </td> <td class="oddnew-M kjCode" nowrap=""> 44850 </td> <td class="oddnew-M kjName" nowrap=""> G-JTOWER </td> <td align="left" class="oddnew-M kjTitle"> <a href="140120240216538929.pdf" target="_blank"> 発行価格等の決定に関するお知らせ </a> </td> <td align="center" class="oddnew-M kjXbrl" nowrap=""> </td> <td align="left" class="oddnew-M kjPlace" nowrap=""> 東 </td> <td align="left" class="oddnew-R kjHistroy"> </td> </tr>
ページソースから
- 欲しい情報はid「main-list-table」となるtableタグ内にある
- tdタグのクラスによってデータの種別を判断可能。例えばkjCodeなら銘柄コード、kjTitleなら表題のようになっている
ことがわかります。これだけわかっていれば欲しい情報を取得可能です。
データ取得に必要そうな情報を表にまとめました。
クラス | 取得可能列 | 備考 |
---|---|---|
kjTime | 開示時刻 | |
kjCode | 銘柄コード | |
kjName | 会社名 | |
kjTitle | 表題 | 内部のaタグhref属性が開示pdfのファイル名、ディレクトリパスは「https://www.release.tdnet.info/inbs/」で共通、aタグのテキストが表題となっている |
kjXbrl | XRBLのパス | 内部のaタグのhref属性がxbrlのファイル名、ディレクトリパスは「https://www.release.tdnet.info/inbs/」で共通 |
kjPlace | 上場取引所 | |
kjHistroy | 更新履歴 |
ページソースをパースし、XBRLのURLを取得する
あとは取得したページソースをパースして、必要情報を取得するだけです。XBRLのURLが取得でき、かつ、表題に「決算短信」というワードが含まれるもののみを選別します。以下がソースです。
import requests from bs4 import BeautifulSoup import urllib.parse r = requests.get('https://www.release.tdnet.info/inbs/I_list_001_20240216.html') soup = BeautifulSoup(r.content, 'html.parser') r.close() xbrl_record_list = list() tr_elms = soup.select('table#main-list-table > tr') for tr_elm in tr_elms : kj_time_str = None kj_code_str = None kj_name_str = None kj_title_str = None pdf_url_str = None xbrl_url_str = None kj_place_str = None kj_history_str = None td_elms = tr_elm.select('td') for td_elm in td_elms : class_list = td_elm.get("class") if 'kjTime' in class_list : kj_time_str = td_elm.get_text().strip() elif 'kjCode' in class_list : kj_code_str = td_elm.get_text().strip() elif 'kjName' in class_list : kj_name_str = td_elm.get_text().strip() elif 'kjPlace' in class_list : kj_place_str = td_elm.get_text().strip() elif 'kjHistroy' in class_list : kj_history_str = td_elm.get_text().strip() elif 'kjTitle' in class_list : a_elm = td_elm.select_one('a') kj_title_str = a_elm.get_text().strip() pdf_name_str = a_elm.get("href") pdf_url_str = urllib.parse.urljoin('https://www.release.tdnet.info/inbs/', pdf_name_str) elif 'kjXbrl' in class_list : a_elm = td_elm.select_one('a') if a_elm != None : xbrl_name_str = a_elm.get("href") xbrl_url_str = urllib.parse.urljoin('https://www.release.tdnet.info/inbs/', xbrl_name_str) else : xbrl_url_str = "" if xbrl_url_str != "" : xbrl_record_list.append(f'{kj_time_str},{kj_code_str},{kj_name_str},{kj_title_str},{pdf_url_str},{xbrl_url_str},{kj_place_str},{kj_history_str}') for record in xbrl_record_list : if '決算短信' in record.split(",")[3] : print(f'{record.split(",")[2]},{record.split(",")[3]},{record.split(",")[5]}')
実行結果
新日本電工,(訂正・数値データ訂正) 「2023 年12 月期 決算短信〔日本基準〕(連結)」の一部訂正に関するお知らせ,https://www.release.tdnet.info/inbs/081220240216538699.zip ピーエイ,令和5年12月期決算短信〔日本基準〕(連結),https://www.release.tdnet.info/inbs/081220240124518831.zip JHD,2023年12月期 決算短信〔日本基準〕(連結),https://www.release.tdnet.info/inbs/081220240215537697.zip ガイアックス,2023年12月期 決算短信〔日本基準〕(連結),https://www.release.tdnet.info/inbs/081220240215538218.zip
決算短信に関連するXBRLのURLを取得できました。
XBRLをダウンロードする
ダウンロード処理については以下で記事にしているのでこちらを参照してください。
取得したXBRLのURLに対してダウンロード処理を行うだけでいいです。
参考
一応、開示情報は全部取得しており、以下のような形で結果を出力することもできます。
取得結果例
23:55,44850,G-JTOWER,発行価格等の決定に関するお知らせ,https://www.release.tdnet.info/inbs/140120240216538929.pdf,,東, 22:22,78160,スノーピーク,本日の一部報道について,https://www.release.tdnet.info/inbs/140120240216538923.pdf,,東, 18:00,26530,イオン九州,代表取締役の異動に関するお知らせ,https://www.release.tdnet.info/inbs/140120240216538875.pdf,,東, 18:00,27880,アップル,定款一部変更に関するお知らせ,https://www.release.tdnet.info/inbs/140120240216538874.pdf,,東, 18:00,36390,ボルテージ,投資有価証券売却益の計上に関するお知らせ,https://www.release.tdnet.info/inbs/140120240216538773.pdf,,東, 18:00,50750,アップコン,業績予想の修正に関するお知らせ,https://www.release.tdnet.info/inbs/140120240216538898.pdf,https://www.release.tdnet.info/inbs/091220240216538898.zip,名, (以下略)
なので、自分がチェックしている会社の開示のみ、または業績の上方修正・下方修正の開示だけをピックアップするなんて使い方も可能です。
おわりに
今回はTDnetをスクレイピングし、決算短信のXBRLをダウンロードする方法について説明しました。次回は東証上場会社情報サービスから決算短信のXBRLをダウンロードする方法について説明したいと思います。
続きは以下です。
www.quwechan.com
今回はここまでです。