前回までの記事では、APIを叩いて過去のビットコインの価格データを取得したり、現在の取引所の板情報を取得する方法を説明しました。
API経由で取得したデータは、大体、以下のように、空白も改行も装飾もない数字と文字の羅列データです。
※bitFlyerのAPIで取得した約定履歴のデータ
このような形式のデータを「JSON形式」といいます。このままの形式だと、どうしていいかわからないと思います。そこで、このJSON形式のデータから欲しい数字だけをPythonで取り出す方法を説明します。
目的の数字だけを取り出す
この記事では、「JSON形式とは何なのか?」といった面倒くさい説明に立ち入ることはしません。興味がある方は自分で調べてみてください。ここでは、いきなり本題に入り、「どうやって目的の数字を探すか?」だけを説明します。
JSON形式のデータは、以下のようなカッコ[]で括られて記述されています。
例
[ 12320 , 12342 , 12246 , 12254]
このように、JSONでは[]で囲まれたデータを1つのまとまりとして扱います。(このような形式を配列値といいます)
そしてプログラムの世界では、これらの[]の中のデータを左から順に、0番目、1番目、2番目、3番目…とカウントします。一番左のデータは[0]、2番目のデータは[1]、3番目のデータは[2]と書いて指定します。
ここまでまずは、覚えておいてください。
JSON形式のデータには、もう1つの記述方法があります。
それが以下のような別のカッコ{}で囲う記述です。
例
{ “btc”:1205314 , “eth”:102478 , “xrp”:89.45 , “xem”:48.42 }
こちらはさっきと違い、1つのデータが「〇〇:××」という2つの値のセットで記述され、それが{}の中にたくさん格納される、という記述の形式です。(このような形式をオブジェクト値といいます)
「〇〇:××」というデータセットのうち、左側の〇〇をキー、右側を値といいます。こちらの{}のデータ形式は、キーを指定することで値の数字を取り出します。例えば、「”btc”:1205314」というデータであれば、btcというキーを指定することで、1205314という値を取り出すことができます。
さっきの[]のデータ形式と違って、順番(〇番目のデータ)で数字を指定することはできません。
はい、覚えるルールはこれだけでOKです。
複雑に見える入り組んだデータ形式
上記のようにJSON形式は、[]や{}のカッコを使ってデータをひとまとめにして扱う形式ですが、実際には、カッコの中にさらにカッコがたくさん入ったような入れ子構造になっている場合が多いです。
例えば、以下のようなイメージです。
{ “中学生”: {“1年生”: {“男子”:[156.5,47.9],”女子”:[153.6,46.7]} , “2年生”: {“男子”:[156.5,47.9],”女子”:[153.6,46.7]} , “3年生”: {“男子”:[156.5,47.9],”女子”:[153.6,46.7]}}, “高校生”: {“1年生”: {“男子”:[156.5,47.9],”女子”:[153.6,46.7]} , “2年生”: {“男子”:[156.5,47.9],”女子”:[153.6,46.7]} , “3年生”: {“男子”:[156.5,47.9],”女子”:[153.6,46.7]}}}
数字は適当なので気にしないでください(笑)
いきなりこれを見ると少し面食らうかもしれませんが、一番内側から分解してみていけば、データの構造がわかります。
データの取り出し方
一番内側のデータセットはこれです。
“男子”:[156,47]
これは左側の”男子”がキーで[156,47]が値のデータセットです。ちなみにこの値は0番目が身長で1番目が体重です。なので、男子の身長の数字にアクセスしたければ、Pythonで[“男子”][0]と書けば、指定できます。
その外側は、
{“1年生” : {“男子”:[],”女子”:[]}}
という構造になっていますね。これは、左側の”1年生”をキーとし、右側の{“男子”:[],”女子”:[]} をまるまる1つの値とするデータセットです。そのため、ここから男子の身長データを取り出したければ、Pythonで[“1年生”][“男子”][0]と書けばOKです。
一番外側の{}を見ると、
{ “中学生”: {1年生のデータ,2年生のデータ,3年生のデータ} , “高校生”:{1年生のデータ,2年生のデータ,3年生のデータ}}
の構造になっているのがわかります。そのため、もし高校2年生の女子の体重データを取り出したければ、Pythonで[“高校生”][“2年生”][“女子”][1]と記述すればいいことがわかります。
bitFlyerのAPIで試してみよう
では同じことを、前回の記事で勉強したbitFlyerのパブリックAPIで試してみましょう。今回は、現在のティッカー情報を取得する以下のAPIを使います。
https://api.bitflyer.jp/v1/ticker/
すると、以下のような結果が得られました(3月現在)
{"product_code":"BTC_JPY","timestamp":"2018-03-12T13:46:52.657","tick_id":2658019,"best_bid":1053564.0,"best_ask":1053565.0,"best_bid_size":0.06,"best_ask_size":0.01,"total_bid_depth":2960.87621693,"total_ask_depth":3323.14800491,"ltp":1053575.0,"volume":273330.16902808,"volume_by_product":25246.19923669}
今ならあなたもこのJSON形式のデータ構造の意味がわかるはずです。
ではPythonのプログラムで、上記のJSONデータから「買い気配値」だけを取り出してみましょう。※ 買い気配値とは、買い板にある注文のうち一番価格の高い注文価格のことをいいます。(参考記事)
Pythonプログラムを書く
サクラエディタを起動して以下のように記述してみましょう。
import requests response = requests.get("https://api.bitflyer.jp/v1/ticker/") data = response.json() print( data["best_bid"] )
一応、いつものようにこのプログラムの意味を説明しておきます。
なお1行目と2行目は前回の記事と同じなのでそちらを参考にしてください。
data = response.json()
URLから取得したJSON形式のデータをパースして、dataという名前の変数に入れます。これは簡単にいうと、pythonに「これはjsonデータだよ!」と教えてる、というくらいの意味に考えてください。この1行を書くことで、JSONデータとして取り扱うことができます。
print ( data[“best_bid”] )
さっきの data というJSONデータから、”best_bid”をキーとする数字を取り出して、それを print() で黒い画面に表示しています。この data[“best_bid”] を自分で書ければ、今回の記事の目標は達成です!
さて、これをAnacondaプロンプトで実行してみると、買い気配値を得ることができました。
長いデータの中から買い気配値だけを取り出すことができました。
もう少しだけ難しい練習問題
今回のデータは、{}が1個しかなくて全体の構造がシンプルだったので、簡単でしたね。もう少しだけ難しいJSONデータのパースに挑戦してみましょう。
前々回の記事で練習した、過去のビットコイン価格のデータを取得するAPIを利用して、2018年1月16日(ビットコインの価格の大暴落があった日)の終値と最安値を取得してみてください。利用するAPIは以下です。
https://api.cryptowat.ch/markets/bitflyer/btcjpy/ohlc?periods=86400&after=1514764800
こちらはさっきより少し難しいですが、まずは自分で試行錯誤してみてください。なお、人間の日付(2018-01-16)を機械のUNIXタイムスタンプに変換するには、こちらのサイトを使ってください。
なお、こちらの練習のプログラムを書くためには、最低限の簡単な「if文」と「for文」を書く必要があります。if文とfor文だけは、プログラムを書く以上、どうしても絶対に勉強する必要があります。全くわからない方は、以下の正解記事を先に読んでおいてください。
正解は、以下の記事で解説しています。
JSONデータの取扱いまとめ
これであなたはPythonを使って、API経由で取得したデータの構造を把握して、目的の数字を自由に取り出すことができるようになりました!
この記事で学んだ内容は、例えば、API経由で「注文の一覧」を取得したり、現在のJPY残高を確認したり、「注文ID」を管理して約定しない注文をキャンセルしたり、自動売買BOTを作るすべての場面で使います。APIのあらゆる結果(レスポンス)はJSON形式で返ってきますので、このスキルは必須です。
次はいよいよ、bitFlyerのプライベートAPIを利用して、買い注文・売り注文を出すために必要なことを学んでいきましょう。