Life is Like a Boat

忘備録や経済、投資、プログラミングに関するメモやtipsなど

Tdnet上の「業績予想の修正に関するお知らせ」のhtmlファイルをパースして、業績に関する数値部分を抽出する

Tdnet上の「業績予想の修正に関するお知らせ」のhtmlファイルをパースして、業績に関する数値部分だけを抜き出す方法です。


Tdnetからダウンロード

まずTdnetにアクセスし、「業種予想の修正に関するお知らせ」を見つけXBRLアイコンをクリックし、zipファイルをダウンロード。
f:id:nerimplo:20180616202811p:plain

ちなみに下記は6/14に発表された第一カッター(1716)の業績予想の修正分です。
https://www.release.tdnet.info/inbs/091220180612462815.zip

zipを解凍し、.htmファイルを開きます。
f:id:nerimplo:20180616202913p:plain


BeautifulSoupでパース

欲しい情報はこのあたりの数値です。
f:id:nerimplo:20180617221205p:plain

from bs4 import BeautifulSoup
import re

PATH = "./091220180612462815/tse-rvfc-17160-20180612462815-ixbrl.htm"

with open(PATH) as f:
    soup = BeautifulSoup(f, 'lxml')

trs = soup.select('table.xbrl_tse.xbrl_table.xbrl_allborder tr')
for tr in trs:
    for ix in tr.find_all('ix:nonfraction', {'unitref': re.compile("JPY|JPYPerShares")}):
        if ix.text:
            print('{:<90}{:<50}{:<50}'.format(ix.attrs.get('contextref'), ix.attrs.get('name'), ix.text))

soup.selectでcss selectorが使えます。私はxpathよりcss selectorの方が馴染み深いのでこちらを使ってます。
tableタグのtrを取得して、さらにその下のix:nonfractionタグに含まれる要素の内容(beautifulsoupのix.text)部分が今回欲しい情報です。

注意したいのが、例えば赤字の営業益の場合です。テキスト部分は営業損失でも正の値となる仕様の様です。この場合、sign属性がタグに含まれるので、ix.attrs.get('sign')が'-'の場合はマイナスの数値に変換してあげる必要があります。




出力結果

これらをcsvに吐くなどして加工できるようにします。

CurrentYearDuration_ConsolidatedMember_PreviousMember_ForecastMember                      tse-ed-t:NetSales                                 14,064                                            
CurrentYearDuration_ConsolidatedMember_PreviousMember_ForecastMember                      tse-ed-t:OperatingIncome                          1,599                                             
CurrentYearDuration_ConsolidatedMember_PreviousMember_ForecastMember                      tse-ed-t:OrdinaryIncome                           1,662                                             
CurrentYearDuration_ConsolidatedMember_PreviousMember_ForecastMember                      tse-ed-t:NetIncome                                1,040                                             
CurrentYearDuration_ConsolidatedMember_PreviousMember_ForecastMember                      tse-ed-t:NetIncomePerShare                        182.83                                            
CurrentYearDuration_ConsolidatedMember_CurrentMember_ForecastMember                       tse-ed-t:NetSales                                 15,848                                            
CurrentYearDuration_ConsolidatedMember_CurrentMember_ForecastMember                       tse-ed-t:OperatingIncome                          2,087                                             
CurrentYearDuration_ConsolidatedMember_CurrentMember_ForecastMember                       tse-ed-t:OrdinaryIncome                           2,161                                             
CurrentYearDuration_ConsolidatedMember_CurrentMember_ForecastMember                       tse-ed-t:NetIncome                                1,305                                             
CurrentYearDuration_ConsolidatedMember_CurrentMember_ForecastMember                       tse-ed-t:NetIncomePerShare                        229.39                                            
CurrentYearDuration_ConsolidatedMember_CurrentMember_ForecastMember                       tse-ed-t:AmountChangeNetSales                     1,783                                             
CurrentYearDuration_ConsolidatedMember_CurrentMember_ForecastMember                       tse-ed-t:AmountChangeOperatingIncome              488                                               
CurrentYearDuration_ConsolidatedMember_CurrentMember_ForecastMember                       tse-ed-t:AmountChangeOrdinaryIncome               499                                               
CurrentYearDuration_ConsolidatedMember_CurrentMember_ForecastMember                       tse-ed-t:AmountChangeNetIncome                    264                                               
PriorYearDuration_ConsolidatedMember_CurrentMember_ResultMember                           tse-ed-t:NetSales                                 12,840                                            
PriorYearDuration_ConsolidatedMember_CurrentMember_ResultMember                           tse-ed-t:OperatingIncome                          1,412                                             
PriorYearDuration_ConsolidatedMember_CurrentMember_ResultMember                           tse-ed-t:OrdinaryIncome                           1,473                                             
PriorYearDuration_ConsolidatedMember_CurrentMember_ResultMember                           tse-ed-t:NetIncome                                990                                               
PriorYearDuration_ConsolidatedMember_CurrentMember_ResultMember                           tse-ed-t:NetIncomePerShare                        174.01