【Python】TDnetから決算短信のXBRLファイルをダウンロード

この記事はアフィリエイト広告を利用しています。

はじめに

自分で決算情報から株価分析を行いたい!という記事になります。
前提としてPythonの知識が少し必要です。(開発環境を自分で設定できる程度)

決算短信関連のコードは検索するとでてくるのですが、説明が多く分かりづらいので、シンプルにコピーするだけで動くコードにしてみました。
決算短信データをダウンロードすることで、あとは自由にデータを加工し分析できるようになります。

TDnetとは

TDnetは東証が提供する上場銘柄の適時開示情報閲覧サービスです。
要するに、各企業のIRニュースをすべて取得することができます。

XBRLファイルとは

XBRLは、財務情報が作成・流通・再利用できるように標準化されたXMLベースの言語です。
XMLベースなのでタグで囲まれた要素が階層になっていますが、実際の決算データはHTMLファイルに記述されているので、そちらを解析することになります。

ソースコード

get_tdnet関数の引数output_dirに保存先のパスを指定するだけで実行できます。(Python3.13.3で動作確認済み)

Warning

開発環境等の影響やTDnetの仕様変更によって正常に動かない場合があります。
エラー処理は入れておりません。
TDnetに負荷をかけないように、初回の実行時にはデバッグ実行をオススメします。

実行環境

実行環境に下記のライブラリをインストールする必要があります。

  • requests
  • BeautifulSoup4
import requests
import urllib.request
import os
from bs4 import BeautifulSoup



実行関数

get_tdnet(output_dir:str)を呼ぶことで実行できます。

引数
output_dir:保存先のパス

def download(soup:BeautifulSoup, output_dir:str):
    table =  soup.find("table",{"id":"main-list-table"})

    # データが無い日
    if table is None:
        return
    
    rows = table.find_all('tr')
    if rows  is None:
        return
    
    for row in rows:
        title = row.find('td', {'class':'kjTitle' })
        if title is None : continue
        text =  title.get_text().replace("\n","").replace(" ","").replace(" ","")
        zip_td =  row.find('td', {'class':'kjXbrl' })
        if text.find('決算短信') != -1 and zip_td.get_text().find('XBRL') != -1 :
            
            code = row.find('td', {'class':'kjCode' }).get_text().replace("\n","").replace(" ","").replace(" ","")[0:-1]
            name = row.find('td', {'class':'kjName' }).get_text().replace("\n","").replace(" ","").replace(" ","")
            
            zip_filename =  zip_td.find('a', {'class':'style002' })['href']
            zip_url = "https://www.release.tdnet.info/inbs/" + zip_filename
            
            dir_path = os.path.join(output_dir, 'XBRL')
            xbrl_path = os.path.join(dir_path, f'{code}_{name}_{text}_{zip_filename}')
            
            # zipファイルがなければダウンロード
            if os.path.exists(xbrl_path) == False:
                ret = urllib.request.urlretrieve(zip_url, xbrl_path)
                print(ret)

    return

def get_tdnet_date(value:str, output_dir:str):

    output_path = os.path.join(output_dir, value)

    # すでにダウンロードしている日にちのファイルはダウンロードしない
    if os.path.exists(output_path) == False:
        url = 'https://www.release.tdnet.info/inbs/'+value
        print(url)
        r = requests.get(url)
        sp2 = BeautifulSoup(r.content, 'html.parser')
        r.close()

        # htmlファイルを保存
        with open(output_path, mode='w',encoding="utf-8") as f:
            f.write(sp2.prettify())

        # XBRLダウンロード
        download(sp2, output_dir)

        # 複数ページにわたっているかチェック
        page_td =  sp2.find("td", {'class': 'pagerTd'})

        if page_td is not None:
            # ページのURLを取得
            pages =  page_td.find_all('div',{'class':'pager-M'})

            for page in pages :
                onclick = page['onclick']
                page_url = onclick.replace("pagerLink","").replace("(","").replace(")","").replace("'","")
                url = 'https://www.release.tdnet.info/inbs/'+page_url

                # すでにダウンロードしているページのファイルはダウンロードしない
                output_path = os.path.join(output_dir, page_url)
                if os.path.exists(output_path) == False:
                    get_tdnet_date(page_url, output_dir)
    return

def get_tdnet(output_dir:str):
    #
    r = requests.get('https://www.release.tdnet.info/inbs/I_main_00.html')
    soup = BeautifulSoup(r.content, 'html.parser')
    r.close()

    # XBRL保存先フォルダを作成
    xbrl_path = os.path.join(output_dir, 'XBRL')
    if os.path.exists(xbrl_path) == False:
        os.makedirs(xbrl_path)

    # htmlファイルを保存
    path = os.path.join(output_dir,'I_main_00.html')
    with open(path, mode='w',encoding="utf-8") as f:
        f.write(soup.prettify())

    #有報の日付ページURLを取得
    select = soup.find("select")
    options = select.find_all("option")

    for option in options:
        value = option['value'] # タグ内の属性を取得できる
        if value == "":
            continue

        get_tdnet_date(value, output_dir)

おわりに

TDnetから決算短信のXBRLファイルをダウンロードする方法を説明しました。
今後ダウンロードしたXBRLファイルを解析して、欲しい情報を取り出すコードも公開予定です。