Pythonでは外部APIを利用することで、データ取得・金融情報・画像処理といった機能を自前で開発せずに短時間で実装できます。しかし「無料で使える」ことと「実務で安全に使える」ことは別問題です。
本記事では、無料で使えるPython向け実用API 10個を実務コード・Rate Limit情報・安全設計パターン付きで紹介します。単なるAPI紹介にとどまらず、プロが実務で外部APIを扱うときの設計思想まで解説します。
対象レベル:初心者〜中級(requests が使える程度)。前提ライブラリ:
pip install requests
APIキーの安全な管理方法については「Pythonセキュリティ実装パターン10選」のシークレット管理セクションも参照してください。
API呼び出しの基本コードテンプレート
個別のAPIを紹介する前に、すべてのAPI呼び出しに共通する基本テンプレートを確認します。実務では、以下の4点を守ることが最低ラインです。
- timeout の設定 — 応答がない場合にプログラムが永遠に待機するのを防ぐ
- ステータスコードの確認 — 200以外のレスポンスを適切に処理する
- 例外処理 — ネットワーク障害やタイムアウトに対応する
- JSON前提にしない — レスポンスがHTMLやテキストの場合にクラッシュしない
import requests
url = "https://api.example.com/data"
try:
response = requests.get(url, timeout=5)
response.raise_for_status()
data = response.json()
print(data)
except requests.exceptions.Timeout:
print("タイムアウト: サーバーが応答しません")
except requests.exceptions.HTTPError as e:
print(f"HTTPエラー: {e.response.status_code}")
except requests.exceptions.RequestException as e:
print(f"リクエストエラー: {e}")
except ValueError:
print("JSONデコードエラー: レスポンスがJSON形式ではありません")
このテンプレートをプロジェクトの共通関数として用意しておくと、API追加のたびにエラー処理を書く手間が省けます。以降のコード例では簡潔さのために省略していますが、本番コードでは必ずこのパターンを適用してください。
無料API 10選 比較一覧
| API | 用途 | APIキー | Rate Limit | 商用利用 | 難易度 |
|---|---|---|---|---|---|
| ① Open-Meteo | 天気・気象データ | 不要 | 緩い | 可 | ★☆☆ |
| ② ExchangeRate | 為替レート | 不要 | 1日1500回 | 可 | ★☆☆ |
| ③ CoinGecko | 仮想通貨価格 | 不要 | 1分10〜30回 | 要確認 | ★☆☆ |
| ④ JSONPlaceholder | テスト・モック | 不要 | なし | — | ★☆☆ |
| ⑤ REST Countries | 国情報・統計 | 不要 | 緩い | 可 | ★☆☆ |
| ⑥ The Cat API | 猫画像 | 任意 | 10回/分 | 可 | ★☆☆ |
| ⑦ IP-API | IP位置情報 | 不要 | 1分45回 | 有料版のみ | ★☆☆ |
| ⑧ Advice Slip | ランダム文章 | 不要 | 2秒間隔 | 可 | ★☆☆ |
| ⑨ PokeAPI | ポケモンデータ | 不要 | 緩い | 可 | ★★☆ |
| ⑩ Numbers API | 数字トリビア | 不要 | 緩い | 可 | ★☆☆ |
① Open-Meteo — APIキー不要の天気API
Open-Meteoは、完全無料・APIキー不要で使える気象データAPIです。現在の天気、気温、風速、降水量から、最大16日間の予報データまで取得できます。商用利用も許可されており、天気関連のツールやアプリを作る際の第一候補になります。
import requests
url = "https://api.open-meteo.com/v1/forecast"
params = {
"latitude": 35.6762,
"longitude": 139.6503,
"current_weather": True
}
response = requests.get(url, params=params, timeout=5)
data = response.json()
weather = data["current_weather"]
print(f"気温: {weather['temperature']}°C")
print(f"風速: {weather['windspeed']} km/h")
このAPIの最大の魅力は認証なしで即座にデータが取れる点です。APIキーの登録やアカウント作成が不要なので、プロトタイプ開発やAPI学習の入口として最適です。緯度・経度を変えるだけで世界中の天気データを取得できます。
Open-Meteoはオープンソースプロジェクトで、欧州の気象機関のデータを利用しています。日本の天気データの精度も高く、個人プロジェクトから商用ツールまで幅広く使えます。
② ExchangeRate API — 為替レートの取得
ExchangeRate APIは、主要通貨の為替レートを無料で取得できるAPIです。通貨変換ツール、価格比較サイト、金融ダッシュボードなど、為替データが必要なプロジェクトで重宝します。APIキー不要で1日1,500回まで利用可能です。
import requests
url = "https://open.er-api.com/v6/latest/USD"
response = requests.get(url, timeout=5)
data = response.json()
jpy_rate = data["rates"]["JPY"]
print(f"1 USD = {jpy_rate} JPY")
# 通貨変換の例
usd_amount = 100
jpy_amount = usd_amount * jpy_rate
print(f"{usd_amount} USD = {jpy_amount:.0f} JPY")
金融データを扱う際の重要な注意点は更新頻度です。このAPIのレートは1日1回程度の更新なので、リアルタイムトレーディングには不向きです。為替レートの大まかな目安や、日次の価格変換には十分な精度があります。
為替レートをユーザーに表示する場合、「このレートは参考値です」と明記してください。リアルタイムレートとのズレが生じる可能性があり、金融取引の根拠として使うべきではありません。
③ CoinGecko API — 仮想通貨の価格・時価総額
CoinGeckoは、ビットコインをはじめとする仮想通貨の価格、時価総額、取引量、ランキングなどを取得できるAPIです。無料プランでもかなり強力なデータが取得でき、仮想通貨関連のツール開発で広く利用されています。
import requests
url = "https://api.coingecko.com/api/v3/simple/price"
params = {
"ids": "bitcoin,ethereum",
"vs_currencies": "jpy,usd",
"include_24hr_change": "true"
}
response = requests.get(url, params=params, timeout=5)
data = response.json()
btc = data["bitcoin"]
print(f"BTC: ¥{btc['jpy']:,.0f} (24h: {btc['jpy_24h_change']:.1f}%)")
CoinGecko APIのRate Limitは無料プランで1分あたり10〜30回程度です。仮想通貨の価格は変動が激しいため、頻繁にAPIを叩きたくなりますが、キャッシュとの組み合わせが必須です。1分ごとにデータを取得してローカルに保存し、表示はキャッシュから返す設計が推奨されます。
CoinGeckoは複数の通貨を1回のリクエストで取得できます。ids=bitcoin,ethereum,solana のようにカンマ区切りで指定すれば、リクエスト数を大幅に削減できます。
④ JSONPlaceholder — API開発練習の定番
JSONPlaceholderは、REST APIの学習・テスト用に設計されたモックAPIです。ユーザー、投稿、コメント、アルバムなどの模擬データを提供しており、API開発のプロトタイプやフロントエンドの開発環境で広く利用されています。
import requests
# 投稿一覧を取得
url = "https://jsonplaceholder.typicode.com/posts"
params = {"_limit": 3}
response = requests.get(url, params=params, timeout=5)
posts = response.json()
for post in posts:
print(f"[{post['id']}] {post['title']}")
# POST リクエストの練習
new_post = {"title": "Test", "body": "Hello", "userId": 1}
res = requests.post(url, json=new_post, timeout=5)
print(f"作成: status={res.status_code}")
JSONPlaceholderの最大の利点はGET・POST・PUT・PATCH・DELETE すべてのHTTPメソッドに対応している点です。POSTやDELETEを送っても実際のデータは変更されず、レスポンスだけが模擬的に返されるため、安心してテストできます。新人エンジニアの教育や、APIクライアントのテストにも最適です。
自分のプロジェクトでモックAPIが必要なら、JSONPlaceholderの設計を参考に json-server(npm パッケージ)を使ってローカルにモックサーバーを立てることもできます。
⑤ REST Countries — 国別の基本情報を一括取得
REST Countriesは、世界各国の基本情報(人口、面積、首都、国旗、通貨、言語、地域など)をJSON形式で取得できるAPIです。地理教育ツール、統計ダッシュボード、国際対応アプリなどで活用できます。
import requests
url = "https://restcountries.com/v3.1/name/japan"
response = requests.get(url, timeout=5)
data = response.json()[0]
print(f"国名: {data['name']['common']}")
print(f"首都: {data['capital'][0]}")
print(f"人口: {data['population']:,}")
print(f"地域: {data['region']}")
print(f"国旗: {data['flag']}")
このAPIは全データがキャッシュ可能という点で実務向きです。国の基本情報はほとんど変わらないため、一度取得したデータをローカルに保存しておけば、以降はAPIを呼ぶ必要がありません。起動時に全データを取得してメモリに保持する設計が効率的です。
/v3.1/all エンドポイントで全250カ国以上のデータを一括取得できます。フィルタ(?fields=name,population,capital)を使えばレスポンスサイズを小さくでき、通信量の節約にもなります。
⑥ The Cat API — 猫画像のランダム取得
The Cat APIは、ランダムな猫画像を取得できるAPIです。一見すると遊びのAPIに見えますが、実務では画像表示のUIテスト、プレースホルダー画像の動的生成、APIクライアントのテストといった用途で意外と重宝します。
import requests
url = "https://api.thecatapi.com/v1/images/search"
params = {"limit": 3}
response = requests.get(url, params=params, timeout=5)
images = response.json()
for img in images:
print(f"URL: {img['url']} (size: {img['width']}x{img['height']})")
APIキーなしでも基本機能は使えますが、無料のAPIキーを登録すると1分あたりのリクエスト上限が増加し、品種フィルタやお気に入り機能も利用できるようになります。画像を多く扱うプロジェクトでは、APIキーの登録をおすすめします。
フロントエンド開発で「画像を動的に表示する機能」のテストが必要なとき、固定のダミー画像よりもこのAPIを使った方が、実際のユースケースに近い状態でテストできます。
⑦ IP-API — アクセス元のIP位置情報
IP-APIは、IPアドレスから国、地域、都市、ISP、タイムゾーンなどの位置情報を取得できるAPIです。アクセス分析、地域別コンテンツ表示、セキュリティ監視などの用途で使われます。
import requests
# 自分のIPの情報を取得
url = "http://ip-api.com/json/"
response = requests.get(url, timeout=5)
data = response.json()
print(f"国: {data['country']}")
print(f"地域: {data['regionName']}")
print(f"都市: {data['city']}")
print(f"ISP: {data['isp']}")
print(f"タイムゾーン: {data['timezone']}")
IP-APIの無料版はHTTPのみ(HTTPSは有料版)です。HTTPS通信が必要な本番環境では、有料プランへの移行か、HTTPS対応の代替サービス(ipinfo.io など)の検討が必要です。また商用利用も有料版のみ許可されています。
Rate Limitは1分あたり45回です。バッチ処理で大量のIPを問い合わせる場合は、http://ip-api.com/batch エンドポイントを使うと効率的です。
⑧ Advice Slip API — ランダムな格言・文章の取得
Advice Slip APIは、ランダムな格言・アドバイスを英語で返すシンプルなAPIです。UIのテスト表示、日替わりメッセージ機能、チャットボットの装飾など、テキストベースのコンテンツ生成に使えます。
import requests
url = "https://api.adviceslip.com/advice"
response = requests.get(url, timeout=5)
data = response.json()
advice = data["slip"]["advice"]
print(f"Today's advice: {advice}")
このAPIの特徴は最小限のエンドポイント設計です。/advice(ランダム)と/advice/{id}(ID指定)だけのシンプルな構造で、REST APIの基本を学ぶ素材としても適しています。ただし、2秒に1回の間隔制限があるため、連続呼び出しには注意が必要です。
このAPIのように「1つのエンドポイントで1つのデータを返す」シンプルなAPIは、API設計の教科書的な参考になります。自分でAPIを作る際にも、まずはこのくらいシンプルな設計から始めるのが実務のベストプラクティスです。
⑨ PokeAPI — 構造化データの学習に最適
PokeAPIは、ポケモンの名前、タイプ、能力値、画像などを取得できるAPIです。一見ゲームデータのAPIですが、ネストされたJSON・ページネーション・リレーション処理など、実務で必要なデータ処理パターンを学ぶのに非常に適した構造になっています。
import requests
url = "https://pokeapi.co/api/v2/pokemon/pikachu"
response = requests.get(url, timeout=5)
data = response.json()
print(f"名前: {data['name']}")
print(f"タイプ: {data['types'][0]['type']['name']}")
print(f"HP: {data['stats'][0]['base_stat']}")
print(f"画像: {data['sprites']['front_default']}")
PokeAPIのレスポンスは深くネストされた構造を持っており、data["types"][0]["type"]["name"] のようなアクセスが必要です。これは実務のAPI(Stripe、Twilio、AWS SDKなど)でもよくあるパターンで、この処理に慣れておくと実務でのAPI統合がスムーズになります。
PokeAPIは1,000体以上のデータを持ち、ページネーション(?offset=20&limit=20)にも対応しています。一覧取得 → 詳細取得のパターンは、そのままECサイトやSNSのAPI設計に応用できます。
⑩ Numbers API — 数字にまつわるトリビア
Numbers APIは、任意の数字に関するトリビア(豆知識)を返すAPIです。教育サイト、雑学クイズ、UI装飾、日替わりコンテンツなどに活用できます。
import requests
number = 42
url = f"http://numbersapi.com/{number}?json"
response = requests.get(url, timeout=5)
data = response.json()
print(f"{number}: {data['text']}")
# 例: 42: 42 is the answer to the Ultimate Question ...
数字の種類として trivia(デフォルト)、math、date、year が指定でき、http://numbersapi.com/3/14/date?json(3月14日のトリビア)のような使い方もできます。
Numbers APIはHTTPのみでHTTPSに対応していません。本番サービスでの利用は避けるか、サーバーサイドで中継してHTTPSレスポンスとしてクライアントに返す設計にする必要があります。
無料API利用の最大の注意点 — Rate Limitとキャッシュ
無料APIで最も危険な落とし穴はアクセス過多(Rate Limit超過)です。無料サービスは制限が厳しく、超過するとIP単位でブロック(いわゆるIP ban)されます。一度banされると解除まで数時間〜数日かかることもあります。
典型的なRate Limit:
| 制限パターン | 例 | 用途 |
|---|---|---|
| 秒単位 | 1秒1回 | リアルタイムデータ |
| 分単位 | 1分60回 | 通常のAPI |
| 日単位 | 1日1,000回 | データ取得系 |
対策はキャッシュです。APIレスポンスをローカルに保存し、一定時間は再リクエストせずにキャッシュから返します。
import requests
import time
import json
import os
CACHE_FILE = "cache.json"
CACHE_TTL = 300 # 5分
def get_with_cache(url):
if os.path.exists(CACHE_FILE):
with open(CACHE_FILE) as f:
cache = json.load(f)
if url in cache and time.time() - cache[url]["time"] < CACHE_TTL:
return cache[url]["data"]
response = requests.get(url, timeout=5)
data = response.json()
cache = {}
if os.path.exists(CACHE_FILE):
with open(CACHE_FILE) as f:
cache = json.load(f)
cache[url] = {"data": data, "time": time.time()}
with open(CACHE_FILE, "w") as f:
json.dump(cache, f)
return data
本番環境ではファイルキャッシュではなく、Redisやmemcachedを使うのが標準です。Djangoにはdjango.core.cache、FastAPIにはaiocacheといったキャッシュフレームワークが用意されています。
実務で必須の安全設計パターン
外部APIを使う実務コードには、以下の5つの設計パターンが必須です。
| パターン | 目的 | 不備時のリスク |
|---|---|---|
| timeout | 無限待機の防止 | プログラムがフリーズ |
| retry | 一時障害への対応 | 一時エラーで処理停止 |
| rate制御 | API制限の遵守 | IP ban |
| fallback | API停止時の代替 | サービス全停止 |
| cache | リクエスト削減 | 制限超過・遅延 |
これらを組み合わせた実務パターンの例:
import requests
import time
def safe_api_call(url, max_retries=3, delay=1):
for attempt in range(max_retries):
try:
response = requests.get(url, timeout=5)
if response.status_code == 429: # Rate Limit
wait = int(response.headers.get("Retry-After", delay * 2))
time.sleep(wait)
continue
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException:
if attempt < max_retries - 1:
time.sleep(delay * (attempt + 1))
continue
return None # fallback
return None
実務ではこの原則を覚えてください:外部APIは「不安定」が前提。停止する、仕様変更がある、レスポンスが遅延する、制限が変更される——これらはすべて「起きるかもしれない」ではなく「必ず起きる」ものです。プロは外部APIを信用しない前提で設計します。
安全な設計の詳細については「Pythonセキュリティ実装パターン10選」も参照してください。
よくある失敗と利用規約の確認ポイント
初心者がやりがちな失敗パターンを把握しておきましょう。
| 失敗パターン | 結果 | 対策 |
|---|---|---|
| forループで連続API呼び出し | IP ban | sleep + キャッシュ |
| キャッシュなしで毎回リクエスト | Rate Limit超過 | ファイル/Redis キャッシュ |
| エラー処理なし | プログラムクラッシュ | try/except 必須 |
| timeout未設定 | プログラムがフリーズ | timeout=5 を標準に |
| 利用規約の未確認 | 法的リスク | Terms/License を必ず読む |
特に利用規約(Terms of Service)は必ず確認してください。無料APIであっても、以下のような制限があるケースが多いです。
- 商用利用禁止 — 個人利用のみ許可のAPI
- クレジット表記必須 — 「Powered by ○○」の表示義務
- 再配布禁止 — 取得データをそのまま別サービスで公開できない
- HTTPS制限 — 無料版はHTTPのみ(IP-API、Numbers APIなど)
「無料 = 自由に使える」ではありません。利用規約を読まずに使うのは、コードにバグを入れるよりも危険です。法的リスクに直結します。
実務者の設計思想 — Provider Abstraction
経験豊富な開発者は、外部APIに対して常にこう考えます。
- 無料APIはプロトタイプ・検証用と位置づける
- 本番化の際は有料プランへの移行、または自前APIへの切り替えを想定する
- APIプロバイダに依存しすぎない設計にする
この思想を実現するのがProvider Abstraction(プロバイダ抽象化)パターンです。API呼び出しを直接コード内に書くのではなく、インターフェースを挟んで差し替え可能にします。
class WeatherProvider:
def get_temperature(self, lat, lon):
raise NotImplementedError
class OpenMeteoProvider(WeatherProvider):
def get_temperature(self, lat, lon):
url = f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}¤t_weather=true"
data = requests.get(url, timeout=5).json()
return data["current_weather"]["temperature"]
class PaidWeatherProvider(WeatherProvider):
def get_temperature(self, lat, lon):
# 有料APIへの切り替えがクラスを変えるだけで完了
pass
# 利用側
weather = OpenMeteoProvider()
temp = weather.get_temperature(35.67, 139.65)
print(f"気温: {temp}°C")
この設計にしておけば、APIプロバイダを変更するときにクラスを1つ差し替えるだけで済みます。アプリケーション全体のコードを書き換える必要がなく、テスト時にはモック用プロバイダに差し替えることもできます。
この設計パターンは「Strategy パターン」とも呼ばれ、APIだけでなくデータベース、メール送信、ファイルストレージなど、外部サービス全般に応用できます。
よくある質問(FAQ)
Q:APIキーが必要なAPIと不要なAPIの違いは?
APIキーは利用者を識別するためのトークンです。キー不要のAPIは手軽ですが、IP単位でのRate Limitが厳しくなる傾向があります。キー有りのAPIは利用者ごとに制限を管理でき、より多くのリクエストが許可されるのが一般的です。
Q:無料APIでサービスを作って公開してもいいですか?
利用規約次第です。Open-MeteoやREST Countriesは商用利用可能ですが、IP-APIの無料版は非商用のみです。必ず各APIの利用規約(Terms of Service)を確認してから公開してください。
Q:APIが突然止まったらどうすればいいですか?
だからこそfallback設計が重要です。キャッシュに直前のデータを保持しておけば、API停止中もキャッシュから表示できます。長期停止の場合はProvider Abstractionパターンで別のAPIに切り替えましょう。
Q:429 Too Many Requestsが返ってきたら?
Rate Limitを超過した合図です。レスポンスヘッダの Retry-After を確認し、指定された秒数だけ待ってからリトライしてください。繰り返し429が返る場合は、キャッシュの導入やリクエスト間隔の見直しが必要です。
まとめ
Pythonで無料APIを活用すれば、天気・為替・仮想通貨・画像など多彩な機能を短時間で実装できます。しかし、本当に重要なのはAPIの選び方ではなく使い方です。
- timeoutとエラー処理を必ず実装する
- Rate Limitを確認し、キャッシュで制限内に収める
- 利用規約を読んでから使う
- Provider Abstractionで依存を管理する
- 外部APIは不安定が前提で設計する
APIは便利ですが、依存すると壊れます。うまく使えば開発速度は劇的に向上します。これが外部API活用の本質です。

コメントを残す