Pythonの軽量ETLライブラリpetlの検証コードの紹介となります。
EDINET 書類一覧API1を用いてJSONデータを取得し、加工、テーブルおよびログを行っています。
検証コード
petltest.py
import logging
import logging.config
import yaml
import requests
import petl
import json
import MySQLdb
from collections import OrderedDict
logger = logging.getLogger(__name__)
def main():
# JSONデータ取得(EDINET API)
res = requests.get("https://disclosure.edinet-fsa.go.jp/api/v1/documents.json?date=2020-09-01&type=2")
# resultsの配列を抽出
jarray = json.loads(res.content)["results"]
# ↓↓↓↓ ここからPETL ↓↓↓↓
# JSON配列をPETLのfromdictsで必要なフィールドだけ抽出
table_base = petl.fromdicts(jarray, header = ["docID", "edinetCode", "filerName", "docDescription", "xbrlFlag"])
# 結果出力
logger.debug(petl.look(table_base))
# フラグxbrlFlagが1のレコードをフィルタリング
table_filtered = petl.select(table_base, lambda rec: rec.xbrlFlag == '1')
# 日付フィールドxbrl_dateを追加
table_addfield = petl.addfield(table_filtered, "xbrl_date", "2020-09-01", 1)
# フラグxbrl_flagのフィールドを削除
table_cutout = petl.cutout(table_addfield, "xbrlFlag")
# ヘッダー変更
table_header = petl.setheader(table_cutout, ["doc_id", "xbrl_date", "edinet_code", "filer_name", "doc_description"])
# DB登録
conn = MySQLdb.connect(user='xxxx',passwd='xxxxxx', host='localhost', db='petltest')
conn.cursor().execute('SET SQL_MODE=ANSI_QUOTES')
petl.todb(table_header, conn, "edinet_docs")
# 集約も!
agglist = OrderedDict()
agglist['cnt'] = len
agglist['docs'] = "doc_id", petl.strjoin(', ')
table_aggregate = petl.aggregate(table_header, "filer_name", agglist)
# スタイル指定結果出力
logger.debug(petl.look(table_aggregate, style='simple'))
# 先頭から10件抽出
table_head10 = petl.head(table_aggregate, 10)
# petl.util.base.Record型リスト化(後にループで処理するためヘッダーを除去)
table_records = petl.records(table_head10)
logger.debug(table_records)
# ループ処理
for record in table_records:
logger.debug("企業名:{}, docIDs:[{}], {}件".format(record.get("filer_name"), record.get("docs"), record.get("cnt")))
if __name__ == "__main__":
logging.config.dictConfig(yaml.load(open("logging.yaml").read(), Loader=yaml.SafeLoader))
main()
結果出力(企業名は加工しています)
最初の結果出力は以下のようになります。
2022-12-15 00:15:31,287 - __main__ - DEBUG - +------------+------------+--------------+----------------+----------+
| docID | edinetCode | filerName | docDescription | xbrlFlag |
+============+============+==============+================+==========+
| 'S100JMSV' | None | None | None | '0' |
+------------+------------+--------------+----------------+----------+
| 'S100JM3Z' | 'E26419' | '株式会社xxxxxx' | '変更報告書' | '1' |
+------------+------------+--------------+----------------+----------+
| 'S100JK18' | None | None | None | '0' |
+------------+------------+--------------+----------------+----------+
| 'S100JMTE' | None | None | None | '0' |
+------------+------------+--------------+----------------+----------+
| 'S100JLX6' | None | None | None | '0' |
+------------+------------+--------------+----------------+----------+
...
スタイル指定結果出力は以下のようになります。
2022-12-15 00:22:37,620 - __main__ - DEBUG - ===================================================================================================================== === ==============================
filer_name cnt docs
===================================================================================================================== === ==============================
'ちxxxxxxxxxxxx株式会社' 2 'S100JKCF, S100JKBL'
'みxxxxxxxxxxxx株式会社' 1 'S100JMLT'
'アxxxxxxxxxxxx株式会社' 3 'S100JL21, S100JL1Z, S100JLYM'
'エxxxxxxxxxxxxLtd' 1 'S100JM9W'
'オxxxxxxxxxxxx株式会社' 3 'S100JMMD, S100JMME, S100JMMH'
===================================================================================================================== === ==============================
...
table_recordsのlogger出力は以下のようになります。
2022-12-15 00:26:08,703 - __main__ - DEBUG - 企業名:ちxxxxxxxxxxxx株式会社, docIDs:[S100JKCF, S100JKBL], 2件
2022-12-15 00:26:08,704 - __main__ - DEBUG - 企業名:みxxxxxxxxxxxx株式会社, docIDs:[S100JMLT], 1件
2022-12-15 00:26:08,705 - __main__ - DEBUG - 企業名:アxxxxxxxxxxxx株式会社, docIDs:[S100JL21, S100JL1Z, S100JLYM], 3件
2022-12-15 00:26:08,706 - __main__ - DEBUG - 企業名:エxxxxxxxxxxxxLtd, docIDs:[S100JM9W], 1件
2022-12-15 00:26:08,708 - __main__ - DEBUG - 企業名:オxxxxxxxxxxxx株式会社, docIDs:[S100JMMD, S100JMME, S100JMMH], 3件
2022-12-15 00:26:08,709 - __main__ - DEBUG - 企業名:キxxxxxxxxxxxxカンパニー, docIDs:[S100JMBC], 1件
2022-12-15 00:26:08,711 - __main__ - DEBUG - 企業名:ケxxxxxxxxxxxxエルエルシー, docIDs:[S100JMRU], 1件
2022-12-15 00:26:08,712 - __main__ - DEBUG - 企業名:フxxxxxxxxxxxx株式会社, docIDs:[S100JK45, S100JK46], 2件
2022-12-15 00:26:08,713 - __main__ - DEBUG - 企業名:フxxxxxxxxxxxx有限会社, docIDs:[S100JMKR], 1件
2022-12-15 00:26:08,714 - __main__ - DEBUG - 企業名:三xxxxxxxxxxxx, docIDs:[S100JMCT], 1件
テーブル出力は以下のようになります。
mysql> select * from edinet_docs limit 5;
+----+------------+----------+-------------+-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------+
| id | xbrl_date | doc_id | edinet_code | filer_name | doc_description |
+----+------------+----------+-------------+-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------+
| 1 | 2020-09-01 | S100JM3Z | E26419 | 株式会社xxxxxxxxxxxx | 変更報告書 |
| 2 | 2020-09-01 | S100J63J | E12430 | xxxxxxxxxxxx株式会社 | 有価証券報告書(内国投資信託受益証券)-第16期(令和1年6月1日-令和2年6月1日) |
| 3 | 2020-09-01 | S100JMOQ | E32064 | xxxxxxxxxxxx有限公司 | 変更報告書 |
| 4 | 2020-09-01 | S100J63F | E12430 | xxxxxxxxxxxx株式会社 | 有価証券届出書(内国投資信託受益証券) |
| 5 | 2020-09-01 | S100JL21 | E10677 | xxxxxxxxxxxx株式会社 | 有価証券報告書(内国投資信託受益証券)-第5期(令和1年6月4日-令和2年6月1日) |
+----+------------+----------+-------------+-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------+
5 rows in set (0.00 sec)
登録に用いたテーブル
create table edinet_docs (
id bigint not null auto_increment comment 'id',
xbrl_date date not null,
doc_id varchar(8) not null,
edinet_code varchar(6),
filer_name varchar(128),
doc_description varchar(256),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
おわりに
評判通り、手軽にETL操作が出来る印象でした。
データが巨大な場合やパフォーマンスを求める場合は当ライブラリは不向きとの情報もあるため2、パフォーマンス面での検証も必要そうです。
-
EDINET 操作ガイド等の「EDINET_API仕様書.pdf」及び「EDINET API利用規約」を参照ください。 ↩