PHPで国立国会図書館を検索

(1/1)
PHP で「国立国会図書館サーチ」を利用し、書籍を検索するプログラムを作ってみる。また、「PHP で ISBN コードを ASIN コードに変換する」を利用し、検索結果を Amazon にリンクさせる。

また、「PHP で Windows用国立国会図書館検索プログラムをつくる」では、このプログラムを Windows アプリに移植したので参考にされたい。

サンプル・プログラム

WebAPI:国立国会図書館サーチ(OpenSearch)

リクエストURL
http://iss.ndl.go.jp/api/opensearch

入力パラメータ
項目名 フィールド名 内  容
タイトル title string 書名、記事名など。UTF-8エンコード。部分一致。
作成者 creator string 著者、編者など。UTF-8エンコード。部分一致。
出版社 publisher string 出版社。UTF-8エンコード。部分一致。
NDC分類 ndc string NDC分類。前方一致。
開始出版年月日 from string 検索を開始する出版年月日。YYYY-MM-DD。
終了出版年月日 until string 検索を終了する出版年月日。YYYY-MM-DD。
出力レコード上限値 cnt int 取得する検索結果の件数。省略時は200。一度に取得できる最大件数は500。
ISBN isbn string ISBNコード。10桁または13桁。前方一致。
資料種別 mediatype int “1”:本
“2”:記事・論文
“3”:新聞
“4”:児童書
“5”:レファレンス情報
“6”:デジタル資料
“7”:その他
“8”:障害者向け資料(障害者向け検索対象資料)
“9”:立法情報
サンプル・プログラムでは、title, isbn の 2 つで検索できるようにする。
応答データ構造(xml) rss channel title 検索結果タイトル link リクエストURL description 検索結果メモ language 言語 item title タイトル link 国会図書館内URL description 内容 category 分類 guid 国会図書館内URL pubDate 出版日 title タイトル titleTranscription タイトル(邦題) volume 巻数 seriesTitle シリーズ・タイトル publisher 出版社 identifier ISBN identifier JPNO subject NDC item title 繰り返し link ...

サンプル・プログラムの解説

0243: /**
0244:  * 国立国会図書館サーチAPI のURLを取得する
0245:  * @param string $query   タイトル(UTF-8;部分一致)
0246:  *                         またはISBN(10桁または13桁;完全一致または前方一致)
0247:  *                         【省略不可】
0248:  * @param string $creater 作成者(UTF-8;部分一致)
0249:  * @param string $from    開始出版年月日(YYYY-MM-DD)
0250:  * @param string $until   終了出版年月日(YYYY-MM-DD)
0251:  * @param int    $cnt     出力レコード上限値(省略時=50)
0252:  * @param int    $mediatype 資料種別(省略時=2:本)
0253:  * @return string WebAPI URL
0254: */
0255: function getURL_searchNDL($query$creater='', $from='', $until='', $cnt=50, $mediatype='1') {
0256:     $isbn = '';
0257:     if (preg_match('/^[0-9|\-]+$/', $query) == 1) {
0258:         $title = '';
0259:         $isbn = 'isbn=' . preg_replace('/\-/', '', $query);
0260:     }
0261:     if ($isbn == '') {
0262:         $title = 'title=' . urlencode($query);
0263:     }
0264: 
0265:     $creater = ($creater != '') ? '&creater=' . urlencode($creater) : '';
0266:     $from    = ($from != '') ? '&from=' . $from : '';
0267:     $until   = ($until != '') ? '&until=' . $until : '';
0268:     $cnt     = ($cnt > 0) ? '&cnt=' . $cnt : '';
0269:     $mediatype = ($mediatype != '') ? '&mediatype=' . $mediatype : '';
0270: 
0271:     return 'http://iss.ndl.go.jp/api/opensearch?' . $title . $isbn . $creater . $from . $until . $cnt . $mediatype;
0272: }
0273: 
0274: /**
0275:  * 国立国会図書館サーチAPIを呼び出し結果を配列に格納する
0276:  * @param array  $items   書籍情報格納用
0277:  * @param string $query   タイトル(UTF-8;部分一致)
0278:  *                         またはISBN(10桁または13桁;完全一致または前方一致)
0279:  *                         【省略不可】
0280:  * @param string $creater 作成者(UTF-8;部分一致)
0281:  * @param string $from    開始出版年月日(YYYY-MM-DD)
0282:  * @param string $until   終了出版年月日(YYYY-MM-DD)
0283:  * @param int    $cnt     出力レコード上限値(省略時=50)
0284:  * @param int    $mediatype 資料種別(省略時=2:本)
0285:  * @return bool TRUE/FALSE
0286: */
0287: function searchNDL(&$items$query$creater='', $from='', $until='', $cnt=50, $mediatype='1') {
0288:     //名前空間
0289:     define('NS_DCMITYPE', 'http://purl.org/dc/dcmitype/');
0290:     define('NS_RDFS', 'http://www.w3.org/2000/01/rdf-schema#');
0291:     define('NS_XSI', 'http://www.w3.org/2001/XMLSchema-instance');
0292:     define('NS_OPENSEARCH', 'http://a9.com/-/spec/opensearchrss/1.0/');
0293:     define('NS_DC', 'http://purl.org/dc/elements/1.1/');
0294:     define('NS_DCNDL', 'http://ndl.go.jp/dcndl/terms/');
0295:     define('NS_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
0296:     define('NS_RCTERMS', 'http://purl.org/dc/terms/');
0297: 
0298:     $url = getURL_searchNDL($query$creater$from$until$cnt$mediatype);
0299: 
0300: //PHP4用; DOM XML利用
0301:     if (isphp5over() == FALSE) {
0302:         if (($dom = read_xml($url)) == NULL)    return FALSE;
0303:         $rss = $dom->get_elements_by_tagname('rss');
0304:         $channel = $rss[0]->get_elements_by_tagname('channel');
0305:         $arr = $channel[0]->get_elements_by_tagname('item');
0306:         //レスポンス・チェック
0307:         $count = count($arr);
0308:         if ($count <= 0)    return FALSE;
0309:         $i = 0;
0310:         foreach ($arr as $item) {
0311:             $isbn = '';
0312:             $node = $item->get_elements_by_tagname('identifier');
0313:             foreach ($node as $val) {
0314:                 if (preg_match('/ISBN/iu', (string)$val->get_attribute('type')) == 1)    $isbn = (string)$val->get_content();
0315:             }
0316:             if ($isbn == '')   continue;
0317:             $node = $item->get_elements_by_tagname('title');
0318:             $items[$isbn]['title'] = ($node == NULL) ? '' : (string)$node[0]->get_content();
0319:             $node = $item->get_elements_by_tagname('creator');
0320:             $items[$isbn]['author'] = ($node == NULL) ? '' : (string)$node[0]->get_content();
0321:             $node = $item->get_elements_by_tagname('publisher');
0322:             $items[$isbn]['publisher'] = ($node == NULL) ? '' : (string)$node[0]->get_content();
0323:             $items[$isbn]['NDC'] = '';
0324:             $node = $item->get_elements_by_tagname('subject');
0325:             foreach ($node as $val) {
0326:                 if (preg_match('/NDC/iu', (string)$val->get_attribute('type')) == 1)    $items[$isbn]['NDC'] = (string)$val->get_content();
0327:             }
0328:             $node = $item->get_elements_by_tagname('link');
0329:             $items[$isbn]['url'] = ($node == NULL) ? '' : (string)$node[0]->get_content();
0330:             $node = $item->get_elements_by_tagname('pubDate');
0331:             $items[$isbn]['pubDate'] = ($node == NULL) ? '' : (string)$node[0]->get_content();
0332:             $node = $item->get_elements_by_tagname('volume');
0333:             if ($node != NULL) {
0334:                 $items[$isbn]['title'] = $items[$isbn]['title'] . '' . (string)$node[0]->get_content() . '';
0335:             }
0336:             $i++;
0337:         }
0338: 
0339: //PHP5用; SimpleXML利用
0340:     } else {
0341:         $xml = @simplexml_load_file($url);
0342:         //レスポンス・チェック
0343:         $count = @count($xml->channel->item);
0344:         if ($count <= 0)    return FALSE;
0345:         $i = 0;
0346:         foreach ($xml->channel->item as $item) {
0347:             $node = $item->children(NS_DC);
0348:             $isbn = '';
0349:             foreach ($node->identifier as $id) {
0350:                 if (preg_match('/ISBN/iu', (string)$id->attributes(NS_XSI)) == 1) $isbn = (string)$id;
0351:             }
0352:             if ($isbn == '')   continue;
0353:             $items[$isbn]['title'] = (string)$node->title;
0354:             $items[$isbn]['author'] = (string)$node->creator;
0355:             $items[$isbn]['publisher'] = (string)$node->publisher;
0356:             $items[$isbn]['NDC'] = '';
0357:             foreach ($node->subject as $id) {
0358:                 if (preg_match('/NDC/iu', (string)$id->attributes(NS_XSI)) == 1) $items[$isbn]['NDC'] = (string)$id;
0359:             }
0360:             $items[$isbn]['url'] = (string)$item->link;
0361:             $items[$isbn]['pubDate'] = (string)$item->pubDate;
0362:             $node = $item->children(NS_DCNDL);
0363:             if ($node->volume != '') {
0364:                 $items[$isbn]['title'] = $items[$isbn]['title'] . '' . (string)$node->volume . '';
0365:             }
0366:             $i++;
0367:         }
0368:     }
0369: 
0370:     return ($i > 0) ? TRUE : FALSE;
0371: }

ユーザー関数 getURL_searchNDL は、タイトル、作成者、開始出版年月日、終了出版年月日、出力レコード上限値、資料種別からリクエスト URL を返す。
タイトルには、書名と ISBN のいずれかを指定可能だ。ユーザー関数内で、数値とハイフンならば ISBN として認識する。
また、タイトル以外は省略可能にしてある。

ユーザー関数 searchNDL は国立国会図書館サーチ API 呼び出し、検索結果を配列に格納する。処理エラーの場合は FALSE を返す。
検索結果の XML 構造は RSS 2.0 に似ており、PHP5(SimpleXML)では名前空間に注意が必要だ。名前空間については「PHP でコロンを含む XML要素名を扱う方法」を参照のこと。

検索結果の ISBN から ASIN を求め Amazon へのリンクを張る部分は、「PHP で ISBN コードを ASIN コードに変換する」のサンプル・プログラムを流用している。
これ以外の部分は、いままで紹介したプログラムと同じである。

参考サイト

(この項おわり)
header