OpenBD APIで書誌情報を取得する方法【TypeScript】

OpenBDは、APIで書誌情報や書影を提供するオープンソースプロジェクトです。個人・法人問わず、SNSやメディアでの書籍の紹介や、アプリケーション内での利用などに自由に利用できます(ガイドライン)。

シバセンセー
シバセンセー

24,747社、約76万タイトルの本の出版社・書影・書評掲載情報などをAPI経由で利用できるぞ。

無料で利用でき、登録も不要であるため手軽にお試しできます。

本記事では、OpenBD APIを紹介した後、TypeScriptでの利用例を掲載します。

APIの使い方

OpenBD APIは、書籍のISBNから書誌情報を取得できるAPIです。例えば、以下のようなURLを呼び出すと、指定したISBNの書誌情報が取得できます。

https://api.openbd.jp/v1/get?isbn=ISBN_xxxxxxxx,ISBN_yyyyyyyy


APIのエンドポイントに、ISBN番号をリクエストパラメーターとして付与します。
一度のリクエストで複数の書誌情報を取得したい場合は、ISBNの値の間にカンマを入れて指定してください。
私が試したところ、リクエストパラメーターはISBNのみ指定することができ、著者などを指定して書誌情報を取得することはできませんでした。

ISBNとは

ISBN番号は、出版物を一意に識別するために与えられたコードです(ISBNと書籍JANコードとは)。書籍の裏表紙や奥付ページに印刷されています。

書籍に記載される ISBNバーコード見本。ISBNと書籍JANコードとはhttps://isbn.jpo.or.jp/index.php/fix__about/fix__about_3/)より引用。

また、OpenBD APIで取得できる書籍の収録範囲は、以下のエンドポイントへリクエストすると、ISBNのリストとして取得できます。

https://api.openbd.jp/v1/coverage

TypeScriptを使った書誌情報取得プログラムの実装例

事前準備

掲載する実装例は、以下の環境にTypeScriptをグローバルインストールし、動作を確認しました。

実行環境
Docker Engine v23.0.5
OS: Ubuntu 22.04
Node.js v20.17.0

設定ファイルは以下のtsconfig.jsonを使用しました。

{"filename":"tsconfig.json","code":"{\r\n  \"compilerOptions\": {\r\n    \"target\": \"ES2015\",\r\n    \"module\": \"commonjs\",\r\n    \"lib\": [\"ES2015\", \"DOM\"],\r\n    \"strict\": true,\r\n    \"esModuleInterop\": true,\r\n    \"skipLibCheck\": true\r\n  }\r\n}\r\n","language":"json","id":19}

package.jsonは以下のようになっています。
今回はnode-fetchというモジュールを使ってAPIを実行します。

{"filename":"package.json","code":"{\r\n  \"dependencies\": {\r\n    \"node-fetch\": \"^2.7.0\"\r\n  },\r\n  \"devDependencies\": {\r\n    \"@types\/node\": \"^22.5.5\",\r\n    \"@types\/node-fetch\": \"^2.6.11\"\r\n  }\r\n}","language":"json","id":19}

書誌情報を取得するプログラムの実装

書誌情報を取得するプログラムをfetchBookData.tsとして実装しました。

APIへのリクエストは10行目のawait fetch(`${url}?${params.toString()}`)で実行しています。残りのプログラムでは取得した書誌情報を整形・出力しています。

{"filename":"fetchBookData.ts","code":"import fetch from 'node-fetch';\r\n\r\nconst url = 'https:\/\/api.openbd.jp\/v1\/get';\r\nconst params = new URLSearchParams({\r\n  'isbn': '9784787220479'\r\n});\r\n\r\nasync function fetchBookData() {\r\n  try {\r\n    const response = await fetch(`${url}?${params.toString()}`);\r\n    \r\n    if (response.ok) {\r\n      const bookData = await response.json();\r\n      if (bookData[0] !== null) {\r\n        \/\/ \u5fc5\u9808\u9805\u76ee\r\n        const title = bookData[0].summary.title;\r\n        const author = bookData[0].summary.author;\r\n        const description = bookData[0].hanmoto?.kaisetsu105w || \"\u6982\u8981\u306f\u3042\u308a\u307e\u305b\u3093\u3002\";\r\n\r\n        \/\/ \u305d\u306e\u4ed6\u6709\u76ca\u306a\u9805\u76ee\r\n        const publisher = bookData[0].summary.publisher;\r\n        const pubdate = bookData[0].summary.pubdate;\r\n        const pages = bookData[0].onix?.DescriptiveDetail?.Extent?.[0]?.ExtentValue;\r\n        const coverUrl = bookData[0].summary.cover;\r\n        \r\n        \/\/ \u66f8\u7c4d\u30b5\u30a4\u30ba\u3092\u53d6\u5f97\r\n        const size = bookData[0].onix?.DescriptiveDetail?.Measure?.map(measure => {\r\n          return `${measure.MeasureType === '01' ? '\u9ad8\u3055' : measure.MeasureType === '02' ? '\u5e45' : '\u539a\u3055'}: ${measure.Measurement}${measure.MeasureUnitCode}`;\r\n        }).join(', ');\r\n\r\n        \/\/ \u51fa\u529b\r\n        console.log(`\u30bf\u30a4\u30c8\u30eb: ${title}`);\r\n        console.log(`\u8457\u8005: ${author}`);\r\n        console.log(`\u6982\u8981: ${description}`);\r\n        console.log(`\u51fa\u7248\u793e: ${publisher}`);\r\n        console.log(`\u51fa\u7248\u65e5: ${pubdate}`);\r\n        console.log(`\u30da\u30fc\u30b8\u6570: ${pages}`);\r\n        console.log(`\u30ab\u30d0\u30fc\u753b\u50cfURL: ${coverUrl}`);\r\n        console.log(`\u66f8\u7c4d\u306e\u30b5\u30a4\u30ba: ${size}`);\r\n\r\n        \/\/ \u66f8\u8a8c\u60c5\u5831\u3092\u3059\u3079\u3066JSON\u5f62\u5f0f\u3067\u51fa\u529b\u3059\u308b\u5834\u5408\u306f\u4ee5\u4e0b\u3092\u5b9f\u884c\r\n        \/\/console.log(JSON.stringify(bookData, null, 2));\r\n\r\n      } else {\r\n        console.log(\"\u6307\u5b9a\u3055\u308c\u305fISBN\u306b\u5bfe\u5fdc\u3059\u308b\u66f8\u7c4d\u60c5\u5831\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3002\");\r\n      }\r\n    } else {\r\n      console.error(`HTTP\u30ea\u30af\u30a8\u30b9\u30c8\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9: ${response.status}`);\r\n    }\r\n  } catch (error) {\r\n    console.error('\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f:', error);\r\n  }\r\n}\r\n\r\nfetchBookData();\r\n","language":"typescript","id":2}

実行方法

実行するには作成したtsファイルをコンパイルしてjsファイルを作成し、実行してください。

tsc fetchBookData.ts
node fetchBookData.js

実行結果

実行結果の例を示します。

今回はタイトルや著者、概要などの情報を抽出して出力しています。

タイトル: 近代日本の都市と農村
著者: 田崎宣義/編著
概要: 都市化の進展、経済格差の拡大やその是正を求める運動、花開いた新しい文化や生活様式など、政治・経済・社会・文化のあらゆる面で「激動の時代」だった1910年代から50年代の都市と農村の実態を、綿密な史料調査から具体的に明らかにする歴史学の成果。
出版社: 青弓社
出版日: 20120324
ページ数: 330
カバー画像URL: https://cover.openbd.jp/9784787220479.jpg
書籍のサイズ: 高さ: 148mm, 幅: 210mm, 厚さ: 20mm, 厚さ: 400gr

書影を取得できるのは大変便利です。以下のURLから、書影を確認してみてください。ただし、書影が収録されていない書籍もありますので、注意してください。

https://cover.openbd.jp/9784787220479.jpg

参考リンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


error: Content is protected !!