隗より始めよ

今後はいろいろ考え始めます。

適時開示情報のzipを開いてhtmファイルをパースする①

f:id:mazarimono:20181027160134j:plain 最近、お酒も飲まずに色々とやっているのですが、今の私には将来の私が楽になれるように頑張ってほしい!ということで、適時開示を開かずとも、決算データが見られるようにということを決算も読まず粛々とやっています。

その途上ですが、一先ず記事にしてみることにしました。

1. 最初に試みた方法

適時開示にあるpdfを全部画像ファイルにして、それを機械学習とかで学ばせ、勝手にこれは良いとか悪いとかやってみようとしました。

しかし、文字データを画像データにしてってのは情報増えないし意味がないという指摘を受けて、それは異なるプロジェクトにすることにしました。

2. requestsとBeautifulSoupを使ってパースする方法を試みる

適時開示のzipファイルをローカルに開いて、htmファイルを探し、そこからデータを探すという方法を取ろうかと試しました。

zipを開いたり、ファイル名を取ってくるのは下のような感じでできます。

import os, zipfile, glob

def open_zip(zip):
    with zipfile.ZipFile(zip) as myzip:
        myzip.extractall('zipfolder')

def glob_htm(open_zip_folder):
    htmlname = glob.glob(open_zip_folder+ '/*.htm', recursive=False)
    htmllist = [html.split('\\')[1] for html in htmlname]
    return htmllist

if __name__ == '__main__':
    open_zip_folder = 'zipfolder'
    target_add = glob_htm(open_zip_folder)

ここからrequestsで読み込んで、BeautifulSoupでパースするかと思いきや、requestsはそのままではローカルファイルを取ってこれないということが分かりました。

で、色々とつらつら読んでいると、requests_fileのFileAdapterを使ったら出来るということで、それを導入したところで気づきました。普通にファイルで読み込んで、正規表現でデータを取ってきたらよいのではないかと・・・

github.com

3. 普通にファイルを開き、正規表現で攻める

正規表現はちょろっと使うことはあるものの、これをメインとしたことはこれまでなかったので、どうすればよいか・・・ということで、大阪Pythonの会にあるIisakaさんの便利サイトを探しました。
達人がまとめられただけあって、これを色々見たら、分かりやすい資料に当たるので、皆さん使ってみてください!

notebooks.azure.com

私はPython module of the Weekで正規表現についてつらつら読み、ちょっとやってみましたが、なんとも難しい・・・。業績データのファイルは以下のように、大体長くて似たようなばかりで、わたしには正規表現で解決するのは無理やなと2,3時間使って思いました。

f:id:mazarimono:20181030140805p:plain

4. 正規表現は避ける案

正規表現とか難しいしやめやめ。というか、requestsとかネットから取るのでないし、いらんかったなぁということで、BeautifulSoup4だけ使うことにしました。

というわけで読み込みは以下のような感じに

from bs4 import BeautifulSoup

soup = BeautifulSoup(open('filename.htm', encoding='utf-8), 'lxml')

これで普通にパース出来ます。
例えば業績修正の発表データを取る場合は、

tables = soup.find_all('table')
for i in tables[1].find_all('td', {'class': 'xbrl_tse xbrl_small'}):
    test_index.append(i.get_text())
    print(test_index)

出力 ['前回発表予想(A)', '今回修正予想(B)', '増減額(B-A)', '増減率(%)', '(ご参考)前期第2四半期実績(平成30年3月期第2四半期)']

業績修正の理由を取る時は

body.find_all('div', {'class': 'xbrl_tse xbrl_text2'})

出力      
[<div class="xbrl_tse xbrl_text2" style="margin-top:25px;"><span style="display:block;font-size:12pt;margin-left:20pt;"><ix:nonnumeric contextref="CurrentYearInstant" name="tse-ed-t:NoticeOfForecastCorrection">最近の業績動向を踏まえ、平成30年4月27日に公表した業績予想を下記の通り修正いたしましたのでお知らせいたします。</ix:nonnumeric></span></div>,
 <div class="xbrl_tse xbrl_text2" style="margin-bottom:10px;"><span style="display:block;margin-left:20pt;"><ix:nonnumeric contextref="CurrentYearDuration" name="tse-ed-t:NoteToFinancialForecast" xsi:nil="true"></ix:nonnumeric> </span></div>,
 <div class="xbrl_tse xbrl_text2" style="margin-top:3px; margin-bottom:30px;"><span style="display:block;margin-left:20pt;"><ix:nonnumeric contextref="CurrentYearDuration" name="tse-ed-t:ReasonForForecastCorrection"><第2四半期累計期間><br/>売上高につきましては、市場を大きく左右する持家着工戸数が、前回発表時の想定を下回る水準で推移したこと、さらに平成30年6月~9月の地震・豪雨・台風によって発生した住宅の補修需要が先行したことによる、一部の新築住宅およびリフォームの着工遅れ・工期の延期等により販売が落ち込み、前回発表予想を下回る見込みです。<br/>損益面につきましては、売上高の減少に加え、原油価格高騰によるエネルギーコスト上昇があり、営業利益、経常利益、当期純利益は前回発表予想を下回る見込みであります。よって上記のとおり修正いたします。<br/><br/><通期><br/>通期の業績予想につきましては、第2四半期累計期間の影響があるものの、売上高につきましては防災瓦の一層の普及活動、ハウスメーカー・工務店への営業活動の強化により、前回発表予想を維持する見込みであります。一方で、原油価格高騰によるエネルギーコスト上昇による影響で、営業利益、経常利益、当期純利益は前回発表予想を下回る見込みです。よって上記のとおり修正いたします。<br/><br/>(注)業績予想につきましては、当社が現在入手している情報及び合理的であると判断する一定の前提に基づいており、実際の業績等は様々な要因により大きく異なる可能性があります。</ix:nonnumeric></span></div>]

てな感じで、業績修正の数値も理由も取れていい感じであります。

問題点

  • 普通の決算発表も数値は取れるのですが、文字データはhtmでは発信されていない。
  • どのようにデータを残すか?
  • このデータをどうやってみるか? ==> Dash良いかも。
  • 文字を学習させる? ==> それなら色んなニュースも学習させる? ==> 自然言語処理って当初やったけど難しかったような・・・

いろいろと課題はありますが、ちょっとずつ進めていきます。