みなさこんにちは!ほぬです!
先日の記事で、東証TDnetから適時開示の一覧を取ってきて保存するものを作成しましたが、そちらの改修版ができましたのでアップします。
どこが改善したかというと、先日の記事で問題だと言っていた
「 ③開示情報の修正が入っている日は取得できない」です!
適時開示ってどんな構造?
そもそも、東京証券取引所のTDnetがどういう感じかというと、↓のような感じになっています。

左上のところで日付を選ぶと、その日に企業が開示した「適時開示」が、1ページ100件ずつ、ザーッと表示されるサイトです。
(過去1ヶ月より以前のものは遡れません。)
上のような、普通の状態のやつは、先日の記事のもので取得できるのですが、↓のように、開示内容に後日修正が入ったようなパターンが取得できませんでした。
↓の画面の真ん中あたりにある緑色で取り消し線が入っているやつですね。
ちなみに、2020年1月31日、2020年2月12日は、修正が入っているせいで前回のものでは取得できません。

できること
今回の改善で、前回課題として残っていた、修正が入った日のものも取得できるようになったので、そもそも最初に写経させていただいたサイトのものでできなかった、
①python上で閲覧するだけなので、その場限りの閲覧になってしまう(保存しておきたい)。
②作成者の方も書いておられますが、開示量が10ページ以上にまたぐ日は取得できない
③開示情報の修正が入っている日は取得できない
が、全部クリアされたと思います!
改めて、今回掲載するものを回せば、
指定した日付の適時開示の一覧を取得し、 直下にある「data」という名前のフォルダに、「tekijikaiji + 日付.csv」というファイル名で保存する
ということができます。
本体
from urllib.request import urlopen
from bs4 import BeautifulSoup
import pandas as pd
from datetime import datetime, date, timedelta
import re
# 日付
yesterday = datetime.today() - timedelta(days=1)
# date = yesterday.strftime('%Y%m%d') #←「昨日」で回したいとき。毎日回すならこちらを活用
date = '20200212' #任意の日付を指定できる
def fn_test(url):
#変数設定
a,b,c,d,e,f = [],[],[],[],[],[] #リストを6つ用意
df = pd.DataFrame() #取得結果格納用のデータフレーム
#ページの閲覧
html = urlopen(url)
bsObj = BeautifulSoup(html, "lxml")
target = re.sub(r'<br/><s>.+</s></td></tr></table></div></td></tr></table></form></body></html>','</td>', str(bsObj))
Obj = BeautifulSoup(target, 'lxml')
tbl3 = Obj.findAll("table")[3]
trs = tbl3.findAll("tr")
for tr in trs:
lst = []
tds = tr.findAll('td')
for td in tds:
#各tdの値を各リストに各々格納
if td.get("class")[1] =="kjTime":a += [td.text ] #開示時刻
if td.get("class")[1] =="kjCode":b += [td.text ] #コード
if td.get("class")[1] =="kjName":c += [td.text ] #社名
if td.get("class")[1] =="kjTitle":d += [td.a.text ] #表題
if td.get("class")[1] =="kjTitle": #pdfのリンクURL
e += ['https://www.release.tdnet.info/inbs/' + td.a.get("href") ] if td.a is not None else [td.a ]
if td.get("class")[1] =="kjXbrl" : #XBRLのDLリンク
f += ['https://www.release.tdnet.info/inbs/' + td.a.get("href") ] if td.a is not None else [td.a ]
lst.append(td)
#取得結果格納リスト群からデータフレーム生成
df = pd.DataFrame(
data={'日付': date, '時刻': a, 'コード': b, '会社名': c, '表題': d, 'url': e, 'XBRL': f},
columns=['日付', '時刻', 'コード', '会社名', '表題', 'url', 'XBRL'])
return df
# URL文字列の生成
url0 = 'https://www.release.tdnet.info/inbs/'
url1 = url0 + 'I_list_{}_{}.html'.format('001',date)
# 該当URLを閲覧
html = urlopen(url1)
bsObj = BeautifulSoup(html, "html.parser")
tbl1 = bsObj.findAll("table")[1]
dv1 = tbl1.findAll("div",{"class":"kaijiSum"})
dv2 = tbl1.findAll("div",{"class":"pager-O"})
dv3 = tbl1.findAll("div",{"class":"pager-M"})
if dv1 ==[]:
print('開示0件')
else:
print(str(dv1).split('全')[1].split('</')[0])
lst =[ range((int(str(dv1).split('全')[1].split('件')[0])//100 + 1))]
if lst ==[]:
df_t = fn_test(url1)
print(df_t)
else:
# ページ数の取得
mxpg= int(str(dv1).split('全')[1].split('件')[0])//100 + 1
print( mxpg )
df_t = pd.DataFrame()
# 再度URL文字列の生成
for i in range(mxpg):
s = str(i + 1)
url1= url0 + 'I_list_{}_{}.html'.format(s.zfill(3) ,date)
print(s , url1)
# ページを逐次閲覧して開示情報を取得
df = fn_test(url1)
df_t = df_t.append(df, ignore_index = True)
df_t.to_csv('./data/tekijikaiji' + date + '.csv', sep = ',', encoding = 'utf-8_sig')
print('finished')
アウトプット
こちらを回すことで、↓のようなcsvファイルが保存されます!

これができたら、次はこれの活用ですね!
例えば、「表題」に特定のキーワードが含まれるものだけに絞り込む、「コード」を使って自分が見たい企業の開示だけを絞り込む、等など、色々活用方法が考えられますね!
今回はここまでになります!また!
ほぬ
※当ブログは、プログラミング初心者が「独学で勉強しながらやってみたらできた」ことを綴っているものです。
※「やってみたらできた」を優先しているため、「やっていいかどうか?」を保証するものではありません。
※ご利用にあたっては、自己責任でお願いいたします。
コメント
[…] 2020/2/22追記この後散々格闘しまして、③適時開示の修正が入っている日のものが取得できない。を、できるようになった、改良版が完成しました。こちらの記事に置いてありますので、そちらを使われたほうがいいかと思います。 […]