はじめに
こんにちは。ITフィールドセールスをしている長井洸太です。
前回までの記事でGitHub APIとQiita APIを使ってエンジニアを自動検索するスクリプトをご紹介しました。
実際に動かしていると、こんなエラーに一度はぶつかります。
429 Too Many Requests
レート制限(Rate Limit)です。大量のデータを取得したい場合、ここを避けて通れません。
この記事では、Qiita APIのレート制限の仕組みを理解して、引っかからずに大量取得する方法をコード付きで解説します。
Qiita APIのレート制限とは
Qiita APIには、一定時間内に叩けるリクエスト数の上限があります。
| 状態 | 上限 | リセット間隔 |
|---|---|---|
| トークンなし(未認証) | 60回 / 時間 | 1時間ごと |
| トークンあり(認証済み) | 1000回 / 時間 | 1時間ごと |
トークンを設定するだけで約16倍の上限になります。まずここから始めましょう。
Qiitaアクセストークンの取得(5分でできる)
- Qiitaにログイン
- 右上のアイコン → 設定
- 左メニュー → アプリケーション
- 「個人用アクセストークンを発行する」 をクリック
- スコープは
read_qiitaのみにチェック - 発行されたトークンを
.envに保存
QIITA_TOKEN=your_token_here
スクリプト側で読み込みます。
from dotenv import load_dotenv
import os
load_dotenv()
QIITA_TOKEN = os.getenv("QIITA_TOKEN", "")
必要なもの
- Python 3.10以上
- Qiitaアクセストークン(上記手順で取得)
pip install requests python-dotenv
レート制限に対応したリクエスト関数
ポイント1:レスポンスヘッダーで残り回数を確認する
Qiita APIのレスポンスには、残りリクエスト数が含まれています。
res = requests.get(url, headers=headers, params=params)
remaining = res.headers.get("Rate-Remaining", "?")
print(f"残りAPI回数: {remaining}回")
Rate-Remaining が少なくなってきたら、処理を一時停止する判断に使えます。
ポイント2:429が返ってきたら60秒待つ
import requests
import time
QIITA_API = "https://qiita.com/api/v2"
def _headers():
h = {"Content-Type": "application/json"}
if QIITA_TOKEN:
h["Authorization"] = f"Bearer {QIITA_TOKEN}"
return h
def search_items_by_tag(tag: str, max_pages: int = 3) -> list:
"""タグで記事を検索して著者IDを収集する"""
author_ids = []
seen = set()
for page in range(1, max_pages + 1):
res = requests.get(
f"{QIITA_API}/items",
headers=_headers(),
params={"query": f"tag:{tag}", "per_page": 100, "page": page},
timeout=15,
)
# 429: レートリミット超過 → 60秒待って同じページをリトライ
if res.status_code == 429:
print("レートリミット超過。60秒待機します...")
time.sleep(60)
continue
if res.status_code != 200:
break
items = res.json()
if not items:
break
for item in items:
uid = item["user"]["id"]
if uid not in seen:
seen.add(uid)
author_ids.append(uid)
remaining = res.headers.get("Rate-Remaining", "?")
print(f" タグ:{tag} page:{page} → {len(items)}記事 (残りAPI: {remaining}回)")
# リクエスト間に0.5秒のインターバルを入れる
time.sleep(0.5)
return author_ids
ポイント3:per_page=100で1リクエストの取得量を最大化
Qiita APIは1リクエストあたり最大100件取得できます。デフォルトは20件なので、必ず per_page=100 を指定しましょう。
params={"query": f"tag:{tag}", "per_page": 100, "page": page}
デフォルトのまま100件取ろうとすると5リクエスト必要ですが、per_page=100 なら1リクエストで済みます。
残り回数が少なくなったら自動停止する実装
def safe_get(url: str, params: dict = None) -> requests.Response | None:
"""残りAPI回数が少ない場合は自動停止するラッパー"""
res = requests.get(url, headers=_headers(), params=params, timeout=15)
if res.status_code == 429:
print("レートリミット超過。60秒待機します...")
time.sleep(60)
return None
remaining = int(res.headers.get("Rate-Remaining", 999))
if remaining < 10:
print(f"残りAPI回数が{remaining}回のため処理を停止します。")
return None
return res
実際にどのくらい取れるか
トークンあり(1000回/時間)で、per_page=100 × 10ページ取得すると:
- 1タグあたり最大 1,000件の記事が取れる
- 著者IDはその中から重複排除するので、タグにもよりますが 200〜400人のエンジニアが収集できる
time.sleep(0.5) を入れると10ページで約5秒。余裕を持ってリクエストできます。
まとめ:レート制限対策チェックリスト
| 対策 | 効果 |
|---|---|
| トークンを設定する | 60回/時 → 1000回/時(16倍) |
per_page=100 を指定 |
1リクエストの取得量を最大化 |
time.sleep(0.5) を挟む |
リクエストを分散して制限に引っかかりにくくする |
| 429が来たら60秒待つ | 自動リトライで止まらずに処理を続ける |
Rate-Remaining を監視する |
残り回数が少なくなったら早めに停止 |
やってみてわかったこと
「制限に引っかかる」より「引っかかる前提で設計する」方が楽
最初は制限に引っかからないように祈りながら動かしていましたが、「429が来たら60秒待つ」の1行を入れてからは、多少のオーバーでも勝手に回復するようになりました。
トークンは必ず設定する
未認証だと60回/時しか叩けず、100件取るだけで枯渇します。5分でできる設定なので最初にやっておくべきでした。
セールス的には「取りすぎない」も大事
1000件のエンジニアリストを作っても、アプローチできる量には限界があります。--min-followers 50 のように絞り込んで質を上げる方が実務では効果的でした。
おわりに
レート制限を理解してから、APIを使った自動収集が格段に安定しました。
次回はGitHub・Qiitaで取得したエンジニア情報をCSVで管理する方法をご紹介します。
毎日X(Twitter)・Instagram・LinkedInでITセールスの日常や自動化ツールの話を投稿しています。ぜひ繋がりましょう!