6.サンプル一覧を取得する - nsaku/xrepo-api-tutorial GitHub Wiki

やること

食レポAPIを使って、サンプル一覧の情報を入手します。

APIで取得できるjson形式のデータは、時には複雑な形をしています。 それを適切に扱うためには、どこにどんなデータが書かれているかが把握できなければなりません。

前項で行った、json.dumpを使ってデータを書き出すことで、データの形を確認する方法を学び、 同時にjson形式についてもう少し深く理解してゆきます。

サンプル一覧を取得するAPI

ブラウザで以下の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のデータに収めてみる

これまで学んだ方法で、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形式での書き出し

前項で行ったように、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の形式についてみてみましょう。

JSONとは、JavaScript Object Notationに由来しており、 ウェブページをインタラクティブにするときによく使われるJavaScriptという言語で扱えるデータを、 テキスト形式で簡潔に表現できるようにしたようなものです。

テキスト形式のためネットを介したやり取りが可能なので、様々な言語でJSONを扱うための仕組み (関数やライブラリ)が提供されており、データの再利用がしやすくなっています。

前項までにも、

requests.get( url ).json()

import jsonjson.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を得て、それを詳しく見てゆくことにより、 どのようなデータでも、このような感じで、構造や、項目名(キー)を正確に理解することができます。

(補足) 「項目名(キー):値」のデータで、「値」の部分には、他のオブジェクトや、配列を入れることもでき、 それを繰り返すことで、複雑なデータを表現できます。

データを見抜くコツは、一番外側が{ }か[ ]かに注目することです。 { }オブジェクトなら、データそのものが一つの大きなオブジェクトなので、各項目(キー)に対応した処理を していけばよいです。

[ ]配列なら、配列の各要素(オブジェクト)に対して「繰り返し処理」をしながら、オブジェクトの中身を それぞれ処理してゆきます。

より詳しくは、トホホ(杜甫々)さんのページに、とても分かり易く簡潔にまとめられていますので、ぜひご覧ください。

http://www.tohoho-web.com/ex/json.html

⚠️ **GitHub.com Fallback** ⚠️