6.サンプル一覧を取得する - nsaku/xrepo-api-tutorial GitHub Wiki
食レポAPIを使って、サンプル一覧の情報を入手します。
APIで取得できるjson形式のデータは、時には複雑な形をしています。 それを適切に扱うためには、どこにどんなデータが書かれているかが把握できなければなりません。
前項で行った、json.dumpを使ってデータを書き出すことで、データの形を確認する方法を学び、 同時にjson形式についてもう少し深く理解してゆきます。
ブラウザで以下のURLにアクセスし、サンプル一覧のjsonを入手してみましょう。
http://metabolites.in/foods/api/samples
下記のような長いjsonテキストが得られたのではないでしょうか?
[{"fid":"01026","nameJa":"こむぎ [パン類] 食パン","nameEn":"Common wheat, bread, white","catJa":"穀類","catEn":"Cereals","descJa":"","descEn":"","dir":"data/170406/01026","mnsid":"SE112_S010261","status":"s1-published","peakNumPos":null,"peakNumNeg":null},{"fid":"01038","nameJa":"こむぎ [うどん・そうめん類] うどん 生","nameEn":"Common wheat, \"Udon\" (thick wheat noodles), uncooked","catJa":"穀類","catEn":"Cereals","descJa":"","descEn":"","dir":"data/170808/01038","mnsid":"SE118_S010381","status":"s1-published","peakNumPos":null,"peakNumNeg":null},{"fid":"01069","nameJa":"こむぎ [その他] ちくわぶ","nameEn":"Common wheat, \"Chikuwabu\" (tube-shaped steamed wheat dough)","catJa":"穀類","catEn":"Cereals","descJa":"","descEn":"","dir":"data/170808/01069","mnsid":"SE118_S010691","status":"s1-published","peakNumPos":null,"peakNumNeg":null},{"fid":"01080","nameJa":"こめ [水稲穀粒] 玄米","nameEn":"Rice, paddy rice, brown rice, raw","catJa":"穀類","catEn":"Cereals","descJa":"","descEn":"","dir":"data/171109/01080","mnsid":"SE122_S010801",
.......
これまで学んだ方法で、pythonのデータに入れられるかを試してみましょう。
test5.pyにこれまで同様にコードを書いてゆきます。
import requests
url = "http://metabolites.in/foods/api/samples"
samples = requests.get( url ).json()
print( samples )
実行してみましょう。 ただ実は、IDLEでは出力できる文字数の制限からか、上記ではうまく結果を確認できません。
そこで、コマンドプロンプトから実行してみます。
> cd C:\Users\sakura\Desktop\python
> py test5.py
{'fid': '01026', 'nameJa': 'こむぎ [パン類] 食パン', 'nameEn': 'Common wheat, bread, white', 'catJa': '穀類', 'catEn': 'Cereals', 'descJa': '', 'descEn': '', 'dir': 'data/170406/01026', 'mnsid': 'SE112_S010261', 'status': 's1-published', 'peakNumPos': None, 'peakNumNeg': None}
{'fid': '01038', 'nameJa': 'こむぎ [うどん・そうめん類] うどん 生', 'nameEn': 'Common wheat, "Udon" (thick wheat noodles), uncooked', 'catJa': '穀類', 'catEn': 'Cereals', 'descJa': '', 'descEn': '', 'dir': 'data/170808/01038', 'mnsid': 'SE118_S010381', 'status': 's1-published', 'peakNumPos': None, 'peakNumNeg': None}
{'fid': '01069', 'nameJa': 'こむぎ [その他] ちくわぶ', 'nameEn': 'Common wheat, "Chikuwabu" (tube-shaped steamed wheat dough)', 'catJa': '穀類', 'catEn': 'Cereals', 'descJa': '', 'descEn': '', 'dir': 'data/170808/01069', 'mnsid': 'SE118_S010691', 'status': 's1-published', 'peakNumPos': None, 'peakNumNeg': None}...
とりあえずデータの格納はうまくいっているようでした。 文字列がシングルクォーテーションで囲まれており、pythonのデータであることが分かります。
ただ、文字列が長いので、どこに何が書いてあるか、そのデータ構造を見抜くのが困難です。
そこで、前項で行ったjson形式の書き出しを行い、データの形を確認してみましょう。
前項で行ったように、json.dumpを使います。"out5.json"ファイルに出力してみましょう。
import requests
import json
url = "http://metabolites.in/foods/api/samples"
samples = requests.get( url ).json()
out_file = "out5.json"
fh_out = open(out_file, "w", encoding="utf-8")
json.dump(samples, fh_out, indent=4, ensure_ascii=False)
fh_out.close()
すると、以下のように整形されて出力されました。
[
{
"fid": "01026",
"nameJa": "こむぎ [パン類] 食パン",
"nameEn": "Common wheat, bread, white",
"catJa": "穀類",
"catEn": "Cereals",
"descJa": "",
"descEn": "",
"dir": "data/170406/01026",
"mnsid": "SE112_S010261",
"status": "s1-published",
"peakNumPos": null,
"peakNumNeg": null
},
{
"fid": "01038",
"nameJa": "こむぎ [うどん・そうめん類] うどん 生",
"nameEn": "Common wheat, \"Udon\" (thick wheat noodles), uncooked",
"catJa": "穀類",
"catEn": "Cereals",
"descJa": "",
"descEn": "",
"dir": "data/170808/01038",
"mnsid": "SE118_S010381",
"status": "s1-published",
"peakNumPos": null,
"peakNumNeg": null
},
....
]
前項の、ダウンロードファイルのサイズを表すデータは、こんな感じでした。
{
"name": "01026_peaks.zip",
"size": 2.530384
}
両者を比較すると、サンプル一覧の情報は、{ }で囲まれた内容が複数、カンマで区切られて[ ]内に 収められていることが分かりました。
ここで改めて、JSONの形式についてみてみましょう。
JSONとは、JavaScript Object Notationに由来しており、 ウェブページをインタラクティブにするときによく使われるJavaScriptという言語で扱えるデータを、 テキスト形式で簡潔に表現できるようにしたようなものです。
テキスト形式のためネットを介したやり取りが可能なので、様々な言語でJSONを扱うための仕組み (関数やライブラリ)が提供されており、データの再利用がしやすくなっています。
前項までにも、
requests.get( url ).json()
や
import json
、json.dump( *** )
などで登場していました。
前項までに、JSONでは、
項目名(キー):値
の形でデータが収められている、というお話をしました。
{
"name": "01026_peaks.zip",
"size": 2.530384
}
ここで、よく見るとこれらの値が{ }でくくられていますが、JSONでは、{ }は「オブジェクト」を指します。
オブジェクト、というのは、決まった構造をしたデータのことを指します。 この場合、「name」と「size」という二つのデータを持ち、それぞれの形は「""」で囲まれた文字列と、 囲まれていない数値です。
サンプル一覧のデータを見ると、この{ }で囲まれたオブジェクトが、複数、[ ]で囲まれていました。
[
{
"fid": "01026",
"nameJa": "こむぎ [パン類] 食パン",
"nameEn": "Common wheat, bread, white",
"catJa": "穀類",
....
},
...
]
JSONでは、[ ]は配列を示します。配列とは、同じデータ構造を持つオブジェクトを、複数持ったものです。
ということで、サンプル一覧のJSONデータの構造を読み解くことができました。 json.dumpを行って整形したjsonを得て、それを詳しく見てゆくことにより、 どのようなデータでも、このような感じで、構造や、項目名(キー)を正確に理解することができます。
(補足) 「項目名(キー):値」のデータで、「値」の部分には、他のオブジェクトや、配列を入れることもでき、 それを繰り返すことで、複雑なデータを表現できます。
データを見抜くコツは、一番外側が{ }か[ ]かに注目することです。 { }オブジェクトなら、データそのものが一つの大きなオブジェクトなので、各項目(キー)に対応した処理を していけばよいです。
[ ]配列なら、配列の各要素(オブジェクト)に対して「繰り返し処理」をしながら、オブジェクトの中身を それぞれ処理してゆきます。
より詳しくは、トホホ(杜甫々)さんのページに、とても分かり易く簡潔にまとめられていますので、ぜひご覧ください。