XBRLをAPI経由で取得する方法 ~Pythonで実装してみる~
EDINETのAPI仕様書(β版)が公開されてる、PDF57ページ分。https://t.co/AoFatld9TZ
— KatoTakahiro@fmbrain.work (@kabkansai) 2018年9月21日
EDINETのAPIの仕様が公開され、XBRL解析する勢はワクワクしています...(たしか公開は2019年3月)
と言いつつ、現状でもAPIは提供されており、そこからXBRLの取得自体は可能です。(提供元は違います)
そもそもXBRLって何って方は、こちらの記事参照。
提供されているのは、有限会社プレシスという会社が有報キャッチャーというAPIです。
(引用)
有報キャッチャーは、EDINETやTDnetで開示されたIR情報をご提供するサービスです。
XBRLデータを活用し、会社属性情報などを整理・閲覧することができます。
APIの使い方はどシンプルなので、記事にするほどでもないのですが、XBRLのフォルダ構成が絡むと少しややこしくなるので備忘含めたメモ的な記事にしておきました。
とりあえず、有報キャッチャーなるAPIを経由したXBRLの取得をPythonで実装してみました記事です。
APIのエンドポイント
http://resource.ufocatch.com/atom/edinet/query/
エンドポイントの末にクエリワード(銘柄コードやEDINETコード)を指定して、リクエストを送ると、EDINETに提出されているドキュメントのURL一覧が返ってきます。
あくまでもレスポンスは、ドキュメントのURL一覧であり、まだXBRLは取得できません。
APIを使ってみる
例えば、「三菱UFJ 日本成長株オープン」という投資信託のドキュメント一覧を取得したければ...
# 三菱UFJ 日本成長株オープンのEDINETコードはG01051 GET http://resource.ufocatch.com/atom/edinet/query/G01051
EDINETコードは、EDINETサイトからCSV形式で取得可能です。
ok google 「EDINETコードを検索して」
と言えばひっかかる気がします。(EDINETはURL長いので貼りたくありませんでした...)
上のリクエストを送ると、レスポンスはこんな感じ。
<?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom"> <title>有報キャッチャー - EDINET情報配信サービス</title> <link href="http://resource.ufocatch.com/" /> <updated>2018-09-22T10:04:03Z</updated> <id>http://resource.ufocatch.com/atom/edinet/query/G01051</id> <entry> <title>【G01051】三菱UFJ投信株式会社 有価証券報告書(内国投資信託受益証券)-第19期(平成29年4月21日-平成30年4月20日)</title> <link rel="alternate" type="text/html" href="http://resource.ufocatch.com/pdfv/ED2018071900080" /> <id>ED2018071900080</id> <docid>S100DKHL</docid> <updated>2018-07-19T09:19:00+09:00</updated> <link rel="related" type="application/zip" href="http://resource.ufocatch.com/data/edinet/ED2018071900080" /> <link rel="related" href="http://resource.ufocatch.com/xbrl/edinet/ED2018071900080/S100DKHL/XBRL/AuditDoc/jpaud-aar-cn-001_E11518-000_2018-04-20_01_2018-07-19.xbrl" type="text/xml" /> <link rel="related" href="http://resource.ufocatch.com/xbrl/edinet/ED2018071900080/S100DKHL/XBRL/AuditDoc/jpaud-aar-cn-001_E11518-000_2018-04-20_01_2018-07-19.xsd" type="text/xml" /> ...
長いので省略しますが...
提出されているドキュメントの一覧が返ってきます。
厳密には提出されているファイルのパスの一覧が返ってくる
提出されているドキュメントの一覧が返ってくるというのは誤りで、キレイな一覧では返ってこないです。
理想は...
$ GET http://resource.ufocatch.com/atom/edinet/query/G01051 http://resource.ufocatch.com/xbrl/edinet/ED2018032300059/2018-03-23に提出された有報.xbrl http://resource.ufocatch.com/xbrl/edinet/ED2018032300059/2017-03-23に提出された有報.xbrl http://resource.ufocatch.com/xbrl/edinet/ED2018032300059/2016-03-23に提出された有報.xbrl http://resource.ufocatch.com/xbrl/edinet/ED2018032300059/2015-03-23に提出された有報.xbrl
みたいな、ドキュメントの一覧なのですが、そうはいきません。
キレイな一覧で返ってこない理由は...
例えば、有報(きっと他のドキュメントも)。
これらは1つの有報というドキュメントを複数ファイルで構成されているからです。
$ GET http://resource.ufocatch.com/atom/edinet/query/G01051 http://resource.ufocatch.com/xbrl/edinet/ED2018032300059/2018-03-23に提出された有報.xbrl http://resource.ufocatch.com/xbrl/edinet/ED2018032300059/2018-03-23に提出された有報の画像.image http://resource.ufocatch.com/xbrl/edinet/ED2018032300059/2018-03-23に提出された有報の一部.htm http://resource.ufocatch.com/xbrl/edinet/ED2018032300059/2017-03-23に提出された有報.xbrl http://resource.ufocatch.com/xbrl/edinet/ED2018032300059/2017-03-23に提出された有報の画像.image http://resource.ufocatch.com/xbrl/edinet/ED2018032300059/2017-03-23に提出された有報の一部.htm ...
イメージで言うと、上記のようなレスポンスになります。
XBRLをダウンロードしたことがあって、中身を見たことがある人はわかると思います。
ダウンロードするとXBRLのファイルだけではなくて、他にもhtmやimageなど色々とあるんですね。
この中でほしいのは、拡張子が.xbrlのファイルだけです。
他はノイズです。
そのため、返ってきたレスポンスの中から.xbrlのパスのみを取得して、その取得したパスを見に行くことでXBRLが取得できます。
Pythonで実装
import requests from bs4 import BeautifulSoup import re import time # エンドポイントにリクエスト response = requests.get("http://resource.ufocatch.com/atom/edinet/query/G01003") response.encoding = response.apparent_encoding # レスポンスをBS4でHTMLを解析 soup = BeautifulSoup(response.text, "lxml") links = soup.find_all("link") # 返ってきた一覧のうち、.xbrlかどうかを正規表現で判別 pattern = ".*PublicDoc.*\.xbrl" for lin in links: result = re.search(pattern , lin.get("href")) # .xbrlであれば、xbrlを取得 if result != None: print(lin.get("href")) response = requests.get(lin.get("href")) response.encoding = response.apparent_encoding print(response.text) else: pass time.sleep(2.0)
少し正規表現の部分を補足すると...
pattern = ".*PublicDoc.*\.xbrl"
拡張子を.xbrlで指定しています。
また、Publicと指定しているのは、EDINET上に公開されている方の情報を取得するためです。
Publicと同じ階層にAuditがあるのですが、こちらは独立監査人用のものなようです(たぶん)。