目次
サンプル・プログラムの実行例
サンプル・プログラム
searchNDL.php | サンプル・プログラム本体。 |
pahooInputData.php | データ入力に関わる関数群。 使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
バージョン | 更新日 | 内容 |
---|---|---|
1.4.0 | 2024/03/09 | API 1.1版に対応,pahooInputData導入 |
1.31 | 2021/01/18 | ISBN検索時に情報不足になることがあり回避策追加 |
1.3 | 2021/01/06 | PHP8対応,エラー処理の厳格化 |
1.2 | 2021/01/05 | 書名読みがな追加,一覧表スタイル変更 |
1.1 | 2017/04/08 | PHP7対応 |
バージョン | 更新日 | 内容 |
---|---|---|
1.5.0 | 2024/01/28 | exitIfExceedVersion() 追加 |
1.4.2 | 2024/01/28 | exitIfLessVersion() メッセージ修正 |
1.4.1 | 2023/09/30 | コメントの訂正 |
1.4.0 | 2023/09/09 | $_GET, $_POST参照をfilter_input()関数に置換 |
1.3.0 | 2023/07/11 | roundFloat() 追加 |
WebAPI:国立国会図書館サーチ(OpenSearch)
URL |
---|
https://ndlsearch.ndl.go.jp/api/opensearch |
フィールド名 | 要否 | 内 容 |
---|---|---|
title | いずれか | 書名、記事名など。UTF-8エンコード。部分一致。 |
creator | いずれか | 著者、編者など。UTF-8エンコード。部分一致。 |
publisher | いずれか | 出版社。UTF-8エンコード。部分一致。 |
ndc | いずれか | NDC分類。前方一致。 |
from | 任意 | 検索を開始する出版年月日。YYYY-MM-DD。 |
until | 任意 | 検索を終了する出版年月日。YYYY-MM-DD。 |
cnt | 任意 | 取得する検索結果の件数。省略時は200。一度に取得できる最大件数は500。 |
isbn | いずれか | ISBNコード。10桁または13桁。前方一致。 |
mediatype | 任意 | 資料種別 “bools”:図書 “periodicals”:雑誌 “articles”:記事 “newspapers”:記事 その他は「データグループ ID・mediaType 一覧」参照 |
解説:初期値設定
15: define('INTERNAL_ENCODING', 'UTF-8');
16: mb_internal_encoding(INTERNAL_ENCODING);
17: mb_regex_encoding(INTERNAL_ENCODING);
18: define('MINUMUM_VERSION', '5.0.0');
19: if (! defined('MYSELF')) {
20: if (isset($_SERVER['SCRIPT_NAME'])) {
21: define('MYSELF', basename($_SERVER['SCRIPT_NAME']));
22: } else if (isset($_SERVER['PHP_SELF'])) {
23: define('MYSELF', basename($_SERVER['PHP_SELF']));
24: } else {
25: define('MYSELF', basename(__FILE__));
26: }
27: }
28: define('REFERENCE', 'https://www.pahoo.org/e-soul/webtech/php06/php06-37-01.shtm');
29: define('TITLE', '国立国会図書館サーチ');
30:
31: //データ入力に関わる関数群:include_pathに配置すること
32: require_once('pahooInputData.php');
33:
34: //PHPバージョン・チェック
35: exitIfLessVersion(MINUMUM_VERSION);
36:
37: //リファラチェック+リリースフラグの設定
38: if (isset($_SERVER['HTTP_HOST']) && ($_SERVER['HTTP_HOST'] == 'localhost')) {
39: define('FLAG_RELEASE', FALSE);
40: define('REFER_ON', '');
41: ini_set('display_errors', 1);
42: ini_set('error_reporting', E_ALL);
43: } else {
44: //リリース・フラグ(公開時にはTRUEにすること)
45: define('FLAG_RELEASE', TRUE);
46: //リファラ・チェック(直リン防止用;空文字ならチェックしない)
47: if (! isCommandLine()) {
48: define('REFER_ON', 'www.pahoo.org');
49: } else {
50: define('REFER_ON', '');
51: }
52: }
53:
54: //入力バリデーション
55: define('QUERY_MIN', 2); //検索文字列の最短
56: define('QUERY_MAX', 40); //検索文字列の最長
57:
58: //表示幅(ピクセル)
59: define('WIDTH', 600);
60:
61: //TRUE:書名読みがなを表示する/FALSE:表示しない
62: define('RUBY', TRUE);
63:
64: //国立国会図書館サーチAPI 1.1(変更不可)
65: define('NDL_URL', 'https://ndlsearch.ndl.go.jp/api/opensearch');
定数 RUBY は、書名読みがな(応答データの dcndl:titleTranscription 要素の内容)をrubyタグを使って表示するか否かのフラグである。
解説:リクエストURL取得
251: /**
252: * 国立国会図書館サーチAPI のURLを取得する
253: * @param string $query タイトル(UTF-8;部分一致)
254: * またはISBN(10桁または13桁;完全一致または前方一致)
255: * 【省略不可】
256: * @param string $creater 作成者(UTF-8;部分一致)
257: * @param string $from 開始出版年月日(YYYY-MM-DD)
258: * @param string $until 終了出版年月日(YYYY-MM-DD)
259: * @param int $cnt 出力レコード上限値(省略時=50)
260: * @param string $mediatype 資料種別(省略時=すべて)
261: * @return string WebAPI URL
262: */
263: function getURL_searchNDL($query, $creater='', $from='', $until='', $cnt=50, $mediatype='') {
264: $isbn = '';
265: if (preg_match('/^[0-9|\-]+$/', $query) == 1) {
266: $title = '';
267: $isbn = 'isbn=' . preg_replace('/\-/', '', $query);
268: }
269: if ($isbn == '') {
270: $title = 'title=' . urlencode($query);
271: }
272:
273: $creater = ($creater != '') ? '&creater=' . urlencode($creater) : '';
274: $from = ($from != '') ? '&from=' . $from : '';
275: $until = ($until != '') ? '&until=' . $until : '';
276: $cnt = ($cnt > 0) ? '&cnt=' . $cnt : '';
277: $mediatype = ($mediatype != '') ? '&mediatype=' . $mediatype : '';
278:
279: return NDL_URL . '?' . $title . $isbn . $creater . $from . $until . $cnt . $mediatype;
280: }
タイトルには、書名とISBNのいずれかを指定可能だ。ユーザー関数内で、数値とハイフンならばISBNとして認識する。
また、タイトル以外は省略可能にしてある。
解説:国立国会図書館検索
282: /**
283: * 国立国会図書館サーチAPIを呼び出し結果を配列に格納する
284: * @param array $items 書籍情報格納用
285: * @param string $errmsg エラーメッセージ格納用
286: * @param string $query タイトル(UTF-8;部分一致)
287: * またはISBN(10桁または13桁;完全一致または前方一致)
288: * 【省略不可】
289: * @param string $creater 作成者(UTF-8;部分一致)
290: * @param string $from 開始出版年月日(YYYY-MM-DD)
291: * @param string $until 終了出版年月日(YYYY-MM-DD)
292: * @param int $cnt 出力レコード上限値(省略時=50)
293: * @param string $mediatype 資料種別(省略時=すべて)
294: * @return int 検索結果の件数
295: */
296: function searchNDL(&$items, &$errmsg, $query, $creater='', $from='', $until='', $cnt=50, $mediatype='') {
297: //名前空間
298: define('NS_DCMITYPE', 'http://purl.org/dc/dcmitype/');
299: define('NS_RDFS', 'http://www.w3.org/2000/01/rdf-schema#');
300: define('NS_XSI', 'http://www.w3.org/2001/XMLSchema-instance');
301: define('NS_OPENSEARCH', 'http://a9.com/-/spec/opensearchrss/1.0/');
302: define('NS_DC', 'http://purl.org/dc/elements/1.1/');
303: define('NS_DCNDL', 'http://ndl.go.jp/dcndl/terms/');
304: define('NS_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
305: define('NS_RCTERMS', 'http://purl.org/dc/terms/');
306:
307: $errmsg = '';
308: $url = getURL_searchNDL($query, $creater, $from, $until, $cnt, $mediatype);
309:
310: $xml = @simplexml_load_file($url);
311: if ($xml == FALSE) {
312: $errmsg = '国立国会図書館サーチAPIの接続に失敗しました.';
313: return FALSE;
314: }
315: //レスポンス・チェック
316: $count = @count($xml->channel->item);
317: if ($count <= 0) {
318: $errmsg = '検索結果がありません.';
319: return (-1);
320: }
321: $cnt = 0;
322: foreach ($xml->channel->item as $item) {
323: //ISBN,書名,著者,出版社,NDC番号,URL,出版日
324: $node = $item->children(NS_DC);
325: $isbn = '';
326: foreach ($node->identifier as $id) {
327: if (preg_match('/ISBN/iu', (string)$id->attributes(NS_XSI)) == 1) {
328: $isbn = (string)$id;
329: }
330: }
331: if ($isbn == '') continue;
332: if ((string)$node->title != '') {
333: $items[$isbn]['title'] = (string)$node->title;
334: } else if (! isset($items[$isbn]['title'])) {
335: $items[$isbn]['title'] = '';
336: }
337: if ((string)$node->creator != '') {
338: $items[$isbn]['author'] = (string)$node->creator;
339: } else if (! isset($items[$isbn]['author'])) {
340: $items[$isbn]['author'] = '';
341: }
342: if ((string)$node->publisher != '') {
343: $items[$isbn]['publisher'] = (string)$node->publisher;
344: } else if (! isset($items[$isbn]['publisher'])) {
345: $items[$isbn]['publisher'] = '';
346: }
347: $items[$isbn]['NDC'] = '';
348: foreach ($node->subject as $id) {
349: if (preg_match('/NDC/iu', (string)$id->attributes(NS_XSI)) == 1) {
350: $items[$isbn]['NDC'] = (string)$id;
351: }
352: }
353: if ((string)$item->link != '') {
354: $items[$isbn]['url'] = (string)$item->link;
355: } else if (! isset($items[$isbn]['url'])) {
356: $items[$isbn]['url'] = '';
357: }
358: if ((string)$item->pubDate != '') {
359: $items[$isbn]['pubDate'] = (string)$item->pubDate;
360: } else if (! isset($items[$isbn]['pubDate'])) {
361: $items[$isbn]['pubDate'] = '';
362: }
363: //巻数,書名読みがな
364: $node = $item->children(NS_DCNDL);
365: if ($node->volume != '') {
366: $items[$isbn]['title'] = $items[$isbn]['title'] . '(' . (string)$node->volume . ')';
367: }
368: $str = (string)$node->titleTranscription;
369: $str = preg_replace('/[ ]/ui', '', $str); //空白除去
370: $str = mb_convert_kana($str, 'c'); //カタカナ→ひらがな変換
371: $items[$isbn]['yomi'] = $str;
372: $cnt++;
373: }
374:
375: return $cnt;
376: }
サンプル・プログラムでは、引数 $query にタイトルまたはISBNを渡すことで検索を行う。$creater 以降の引数はデフォルト値のままにしてあるが、ぜひ、これらの引数を利用したプログラムを作ってみてほしい。
検索結果のXML構造はRSS 2.0に似ており、PHP5(SimpleXML)では名前空間に注意が必要だ。名前空間については「PHPでコロンを含むXML要素名を扱う方法」を参照のこと。ここでは、各々の名前空間を定数で定義している。
検索結果のISBNからASINを求めAmazonへのリンクを張る部分は、「PHPでISBNコードをASINコードに変換する」のサンプル・プログラムを流用している。
エラーが発生した場合、引数 $errmsg にエラーメッセージを格納する。エラーがなければ空文字を代入する。
質疑応答
「PHPで国立国会図書館を検索」のページ大変参考になります。使用させていただきたいと思っています。【回答】
ところで、本のタイトルの読みはXMLでは <dcnl:titleTranscription> とあるのですが、上記のPHPでフリガナの取得はできないのでしょうか。どのようにすれば可能なのでしょうか?教えていただけませんか。
本のサイズ<extent>は何とか取得することができたのですが。
<dc;title>などと <dcnl:titleTranscription> などとの記述の違いが判りません。
教えていただけるとありがたいのですが。
お気づきのように、WebAPIの応答にある <dcnl:titleTranscription> に書名の読み仮名(全角カタカナ)が入っています。【質問】
読みがなを含めて取得・表示するようプログラムを改良しました。お試しください。
ルビ入りのプログラムを作成くださりありがとうございます。参考にさせていただきます。【回答】
今後ともよろしくお願いいたします。
どういたしまして😀【質問】
ご活用ください。
たびたびお世話になります。【回答】
貴重なプログラムなので活用させていただいています。
「鬼滅の刃」を検索すると著者名まで表示されるのですが、その中の1つのISBNで検索してみると、それでは著者名が表示されません。
どうしてそのような違いが生じるのか、よくわかりません。はじめはそのデータが登録されていないのかと同様のことをいろいろやってみても同じような状況になります。コミックだからでしょうか。
author creator 違いなのかと代えてもみても、うまくいきません。
authorを使用するところとcreatorを使用する個所とがあるのでしょうか。
ISBNで検索する場合、ISBNが単一(1つの書籍)であるにもかかわらず、複数の結果が還ってくることがあります。どうやら国立国会図書館サーチの仕様のようです。
そこで、複数の結果が返ってきたときは、一番最後の有効な値を表示するようにプログラムを改良しました。
ここで、「ISBN=9784088812830」(『鬼滅の刃』第9巻)を検索すると、書名に「遊郭潜入大作戦」と表示されます。これは、国立国会図書館サーチが返す複数の結果の最後が、書名にサブタイトルが入っているためです。いまのところ、書名なのかサブタイトルなのかを判断する情報がないため、プログラムの改良はここまでとします。
参考サイト
- 国立国会図書館サーチ
- C++で国立国会図書館検索:ぱふぅ家のホームページ
- PHPでコロンを含むXML要素名を扱う方法:ぱふぅ家のホームページ
- PHPでISBNコードをASINコードに変換する:ぱふぅ家のホームページ
- PHPで楽天ブックスAPIを使って書籍検索:ぱふぅ家のホームページ
また、「C++で国立国会図書館検索」では、このプログラムをWindowsアプリに移植したので参考にされたい。
(2024年3月9日)API 1.1版に対応,pahooInputData導入