Web API

R版

はじめに

2022年度から学年進行で施行される高等学校学習指導要領解説の「情報編」には,APIの利用について,次のような記述がある:

例えば,気象データや自治体が公開しているオープンデータなどを用いて数値の合計,平均,最大値,最小値を計算する単純なアルゴリズムや,探索や整列などの典型的なアルゴリズムを考えたり表現したりする活動を取り上げ,アルゴリズムの表現方法,アルゴリズムを正確に表現することの重要性,アルゴリズムによる効率の違いなどを扱うことが考えられる。その際,アルゴリズムを基に平易にプログラムを記述できるプログラミング言語を使用するとともに,アルゴリズムやプログラムの記述方法の習得が目的にならないよう取扱いに配慮する。

また,プログラミングによってコンピュータの能力を活用することを取り上げ,対象に応じた適切なプログラミング言語の選択,アルゴリズムをプログラムとして表現すること,プログラムから呼び出して使う標準ライブラリやオペレーティングシステム及びサーバなどが提供するライブラリ,API(Application Programming Interface)などの機能,プログラムの修正,関数を用いてプログラムをいくつかのまとまりに分割してそれぞれの関係を明確にして構造化することなどを扱うことが考えられる。その際,プログラミング言語ごとの固有の知識の習得が目的とならないように配慮する。

更に問題解決のためのプログラミングを取り上げ,プログラミングでワードプロセッサや表計算ソフトウェアのようなアプリケーションソフトウェアが持つ検索や置換及び並べ替えなどの機能の一部を実現したり,ツールやアプリケーションを開発したり,カメラやセンサ及びアクチュエータを利用したり,画像認識や音声認識及び人工知能などの既存のライブラリを組み込んだり,APIを用いたりすることなどが考えられる。その際,人に優しく使いやすいインタフェース,手順を分かりやすく表現するアルゴリズム,効率的で読みやすいプログラムなどのデザインについて触れる。

オープンデータをAPIで取得するプログラムを作れと言っているようにも読める。実際,2019年5月に出た文科省高等学校情報科「情報Ⅰ」教員研修用教材には,第3章に郵便番号検索APIをPythonで叩く例が載っている。

2020年1月に出た教育用プログラミング言語ドリトルv3.3には,Web APIを扱う機能が付け加えられ,5通りのサンプルプログラムが付いている。

以下では,これらを参考に,無登録で使えるWeb APIをPythonで使う例を紹介する。

郵便番号検索API

株式会社アイビスが提供している郵便番号検索API

import requests

url = "https://zipcloud.ibsnet.co.jp/api/search"
param = {"zipcode": "5140007"}
data = requests.get(url, param).json()

# 上の3行は次の2行と同じことである:
# url = "https://zipcloud.ibsnet.co.jp/api/search?zipcode=5140007"
# data = requests.get(url).json()

address = data["results"][0]
print(address["address1"], address["address2"], address["address3"])

入力を含むプログラム:

#! /usr/bin/env python3

import requests

url = "https://zip-cloud.appspot.com/api/search"
while True:
    z = input("7桁の郵便番号を入力してください: ")
    if not z:
        break
    print(z)
    param = {"zipcode": z}
    data = requests.get(url, param).json()
    address = data["results"][0]
    print(address["address1"], address["address2"], address["address3"])

気象庁API

2021-02-24 13:00:00 のリニューアルによってさまざまなAPI(とは気象庁は言っていない)が使えるようになったようだ。例:

url = "https://www.jma.go.jp/bosai/forecast/data/overview_forecast/240000.json"
data = requests.get(url).json()
print(data['headlineText'])
print(data['text'])

(参考)アシアル岡本さんの気象庁の天気予報JSONファイルをWebAPI的に利用したサンプルアプリ,加納靖之先生の気象庁の新しい地震情報をみてみた

Weather Hacks

なくなってしまった;_;

livedoor(LINE Corporation)の提供するWeather Hacksは,場所を指定すると天気予報が取得できる。詳細はWebサービス仕様参照。

url = "http://weather.livedoor.com/forecast/webservice/json/v1"
param = {"city": "240010"} # 三重県津市
data = requests.get(url, param).json()
for x in data["forecasts"]:
    print(f'{x["dateLabel"]}の天気: {x["telop"]}')

openBD

カーリル版元ドットコムopenBDは書誌情報・書影を提供する。

url = "https://api.openbd.jp/v1/get"
param = {"isbn": "978-4-7741-9690-9"}
data = requests.get(url, param).json()
print("著者名:", data[0]["summary"]["author"])
print("書名:", data[0]["summary"]["title"])
print("出版社名:", data[0]["summary"]["publisher"])
print("出版年月:", data[0]["summary"]["pubdate"])

HeartRails Express

ハートレイルズHeartRails Expressは路線/駅名データ等の地理情報を提供する。

url = "http://express.heartrails.com/api/json"

param = {"method": "getLines", "prefecture": "三重県" }
data = requests.get(url, param).json()
print("路線名一覧:")
for i in data["response"]["line"]:
    print(i)

param = {"method": "getStations", "line": "近鉄名古屋線" }
data = requests.get(url, param).json()
print("駅と経度・緯度:")
for i in data["response"]["station"]:
    print(i["name"], i["x"], i["y"])

お菓子の虜

鳥山優子さんのコンビニお菓子の情報サイトお菓子の虜Web API

url = "https://sysbird.jp/toriko/api/"
param = {"apikey": "guest", "format": "json", "keyword": "マシュマロ" }
data = requests.get(url, param).json()
print("菓子名・メーカー:")
for i in data["item"]:
    print(i["name"], i["maker"])

Google Calendar API

ここに書かれている通りにすれば,Pythonの簡単なプログラムからGoogle Calendarの予定を取り出すことができる。

Geolonia 住所データ

Geolonia住所データ は全国の町丁目レベル(189,540件)の住所を収録したもの。CSVでダウンロードできるほか,APIとしても提供されている。

例:三重県の全自治体名を出力

import requests

url = "https://geolonia.github.io/japanese-addresses/api/ja.json"
data = requests.get(url).json()
for i, x in enumerate(data['三重県']):
    print(i + 1, x)

例:三重県津市の全町名を出力

import requests
import urllib.parse

query = "三重県/津市"

url = "https://geolonia.github.io/japanese-addresses/api/ja/"
data = requests.get(url + urllib.parse.quote(query) + ".json").json()
for i, x in enumerate(data):
    print(i + 1, x)

その他の登録不要のAPI(お教えいただいたもの)

取り過ぎに注意

あまり頻繁に同じデータにアクセスすると遮断されることがありうる。対策として,Google ColabやJupyter Notebookなら,データ取得部分は試行錯誤が必要な部分とセルを分ける。例:

# このセルは最初に1回だけ実行
import pandas as pd

URL = "https://www.jma.go.jp/bosai/quake/data/list.json"
df = pd.read_json(URL)

一般の場合は,いろいろ手がありそうだが,例えば次のようにすれば,まずはカレントディレクトリにすでにファイルがあればそのタイムスタンプから600秒(10分)経っていなければそのファイルを読むだけにする。そうでなければ wget -N によりファイルをダウンロードするが,カレントディレクトリにすでにファイルがあればそのタイムスタンプより新しいものが提供されていない限りダウンロードしない。

#! /usr/bin/env python3

import os
import time
import pandas as pd

URL = "https://www.jma.go.jp/bosai/quake/data/list.json"

try:
    t = os.stat("list.json").st_mtime
except:
    t = 0
if time.time() - t > 600:  # 初回か10分より古ければ再取得
    os.system("wget -N " + URL)
df = pd.read_json("list.json")
...

今は os.system() より subprocess.run() が推奨されている。こちらを使えば例えば次のようにできる。

import subprocess

r = subprocess.run(["wget", "-N", URL],
                   capture_output=True, text=True,
                   env={"PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin",
                        "LANG": "en"})

if not " saved " in r.stderr:
    print("Not saved.")  # 304 Not Modified
    exit()

df = pd.read_json(...)

NATしている大学のPC教室だと,全員が同じIPアドレスになるので,演習で一斉に同じデータにアクセスしたら,DOS攻撃と間違えられて遮断される危険があるかもしれない。


Last modified: