特許庁が提供する 特許情報取得API は、
特許検索・経過管理・知財DXに非常に有用です。
しかし、
- ブラウザから直接呼べない(CORS制限)
- ID・パスワードをJavaScriptに書けない
- トークン管理が難しい
という理由から、Node.jsによるプロキシサーバ構築が実質必須になります。
本記事では、
👉 Node.jsのインストール(環境構築)
👉 プロキシAPIサーバ作成
👉 ブラウザ検索アプリ作成
まで、完全な手順書として解説します。
今回はRaspberry pi5のRaspberry
Pi OSを使用しています。Ubuntuでも可能と思いますが、動かない場合は適宜手直ししていただれば幸いです。
1. Node.js をインストールする(最初にやること)
1-1. Node.jsとは?
Node.js は JavaScriptをサーバ側で動かす実行環境
です。
今回のプロキシAPIサーバは Node.js で作成します。
1-2. Node.jsのインストール方法
✅ Linux(Raspberry Pi OS 、Ubuntu)
sudo apt update
sudo apt install nodejs npm
または、Node.jsを、以下のコマンでインストールします。
# 例えば、Node.js 18.x をインストール
curl -fsSL
https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
1-3. インストール確認
ターミナル(コマンドプロンプト)で以下を実行します。
node -v
npm -v
バージョンが表示されれば成功です。
2. プロジェクトフォルダを作成する
mkdir jpo-api-sample
cd jpo-api-sample
3. Node.jsプロジェクト初期化
npm init -y
必要なライブラリをインストールします。
npm install express cors dotenv
4. 環境変数ファイル(.env)を作成
プロジェクト直下に .env を作成し、以下を記述します。
JPO_USERNAME=あなたの特許庁APIユーザーID
JPO_PASSWORD=あなたの特許庁APIパスワード
⚠️ このファイルはGitHub等に公開しないでください
5. ① server.js(Node.js
プロキシAPIサーバ)
以下を server.js として保存してください
(コードはそのままコピー&ペーストでOKです)。
// server.js — app_progress 専用版
import express from "express";
import cors from "cors";
// Node.js v18+ は
fetch が標準搭載
import "dotenv/config";
const app = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true
}));
// ==================================
// トークンキャッシュ
// ==================================
let cachedToken = null;
let tokenExpireAt = null;
// ==================================
// 特許庁 API: トークン取得
// ==================================
async function fetchTokenFromJpo() {
const url = "https://ip-data.jpo.go.jp/auth/token";
const params = new
URLSearchParams();
params.append("grant_type", "password");
params.append("username",
process.env.JPO_USERNAME);
params.append("password",
process.env.JPO_PASSWORD);
const response = await fetch(url, {
method:
"POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded" },
body: params
});
const data = await response.json();
if (data.access_token) {
cachedToken =
data.access_token;
tokenExpireAt =
Date.now() + data.expires_in * 1000 - 5000; // 期限5秒前更新
}
return data;
}
// ==================================
// 有効なトークンを返す関数
// ==================================
async function getValidToken() {
const now = Date.now();
if (cachedToken &&
tokenExpireAt && now < tokenExpireAt) {
return cachedToken;
}
const newToken = await
fetchTokenFromJpo();
return newToken.access_token;
}
// ==================================
// 1) トークン取得 API
// ==================================
app.post("/api/token", async
(req, res) => {
try {
const token = await
getValidToken();
res.json({
access_token: token,
cached:
token === cachedToken
});
} catch (e) {
res.status(500).json({
error: e.toString() });
}
});
// ==================================
// 2) app_progress(特許経過情報)
// 出願番号(10桁)例: 2023063418
// ==================================
app.get("/api/app_progress/:number",
async (req, res) => {
try {
const token = await
getValidToken();
const number =
req.params.number;
const url =
https://ip-data.jpo.go.jp/api/patent/v1/app_progress/${number};
const response = await
fetch(url, {
headers: {
"Authorization": Bearer ${token}
}
});
const text = await
response.text();
//
-------------------------------
// JSON でも HTML でも安全に返す
//
-------------------------------
try {
const json =
JSON.parse(text);
return
res.status(response.status).json(json);
} catch {
return
res.status(response.status).json({
error: "JPO API returned non-JSON response",
status: response.status,
body: text
});
}
} catch (e) {
res.status(500).json({
error: e.toString() });
}
});
// ==================================
// サーバ起動
// ==================================
app.listen(3000, () => {
console.log("✅ app_progress 専用 JPO Proxy Server 起動!");
console.log("✅ トークン取得:
POST http://localhost:3000/api/token");
console.log("✅ 経過情報: GET http://localhost:3000/api/app_progress/{出願番号}");
});
6. サーバを起動する
node server.js
以下が表示されれば成功です。
✅ app_progress 専用 JPO Proxy Server 起動!
7. ② ブラウザアプリ(index.html)
次に、検索用のHTMLを作成します。
以下を index.html として保存し、ブラウザで開いてください。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta
charset="UTF-8">
<title>特許経過情報(app_progress)検索</title>
<style>
body {
font-family:
sans-serif;
margin: 40px
auto;
max-width:
700px;
}
label {
font-weight:
bold;
}
input {
width: 100%;
padding:
8px;
margin: 8px
0 16px 0;
font-size:
16px;
}
button {
padding:
10px 20px;
font-size:
17px;
cursor:
pointer;
}
pre {
background:
#f7f7f7;
border: 1px
solid #ccc;
padding:
15px;
white-space:
pre-wrap;
margin-top:
20px;
}
</style>
</head>
<body>
<h2>📄 特許経過情報(app_progress)検索</h2>
<label>出願番号(10桁数字:例 2023063418)</label>
<input id="appNumber"
placeholder="2023063418">
<button onclick="search()">検索する</button>
<pre id="result">ここに検索結果が表示されます</pre>
<script>
async function search() {
const num =
document.getElementById("appNumber").value.trim();
const result =
document.getElementById("result");
if (!num.match(/^[0-9]{10}$/)) {
result.textContent =
"⚠️ 出願番号は10桁の数字を入力してください。";
return;
}
result.textContent = "問い合わせ中…";
try {
const res = await
fetch(http://localhost:3000/api/app_progress/${num});
const json = await
res.json();
result.textContent =
JSON.stringify(json, null, 2);
} catch (err) {
result.textContent =
"エラーが発生しました:\n" + err;
}
}
</script>
</body>
</html>
8. 動作確認
- server.js を起動
- index.html をブラウザで開く
- 出願番号を入力して検索
👉 特許庁の
経過情報(app_progress) が表示されます。
まとめ
✅ Node.jsインストールからスタート
✅ セキュアな特許庁APIプロキシ構築
✅ ブラウザ検索UI完成
この構成を使えば、
- 社内システム連携
- Excel / Power BI 連携
- AI・分析基盤への接続
まで、知財DXの土台がすぐに作れます。