学習007 国立国会図書館サーチのAPIを引用できるWordPress用プラグインを開発

読書感想文を書くにあたって、書影を表示したりするのに、Google Books APIを活用していました。

しかし、この数カ月で、Google Books APIに登録があったはずの書籍データが次々になくなって、このサイトで表示できていた書籍データが表示されなくなっています。特に法則性もなく、半分近い割合なので、正直、使い物になりません。

Google Books APIは、APIの一時的なリクエスト数が上限に達したことによると思われるエラーもよく発生していました。仕方ないので、最初に使っていた国立国会図書館サーチのAPIに戻ることに。

Google Books APIに移行した理由の一つに、Google Books APIはJSONデータを吐き出してくれるので、JSON Content ImporterというWordPress用のプラグインを使えるということがありました。一方で、国立国会図書館サーチのAPIは、書影はJPEGをそのまま吐き出してくれるので単純で当時の私でも活用できましたが、その他はXML形式で、使いこなせていなかったのです。

これは、もしかしたらChatGPT先生に頼ったらうまくいくのではないかと、調べてみたところ、WordPress用のプラグインを一日で作れてしまいました。

↑のような感じで最初に頼んだら、それなりに動くプラグインを一発で出力してくれて、本当に驚きました。ショートコードなんてしくみがWordPressにあることも、この時のChatGPTの回答で初めて知りました。

その後、国立国会図書館サーチAPIが吐き出す著者情報が、「姓,名,姓名,生年」「姓,名,生年」みたいにいろんなバリエーションがあって、さらには翻訳者情報まで絡んできてぐちゃぐちゃだったりして苦労しつつも、自分で使う分には十分納得できるプラグインが完成。

<?php
/*
Plugin Name: Book Info Display
Description: Displays book information using a shortcode and NDL APIs.
Version: 1.0
Author: T Matsuoka 
*/

add_shortcode('book_info', 'display_book_info');

function display_book_info($atts) {
    $atts = shortcode_atts([
        'isbn' => ''
    ], $atts, 'book_info');

    $isbn = sanitize_text_field($atts['isbn']);

    if (!$isbn) {
        return '<p>ISBNコードを指定してください。</p>';
    }

    // NDL APIのURL
    $api_url = 'https://iss.ndl.go.jp/api/opensearch?isbn=' . urlencode($isbn);
    $thumbnail_url = 'https://ndlsearch.ndl.go.jp/thumbnail/' . urlencode($isbn) . '.jpg';

    // APIレスポンスを取得
    $response = wp_remote_get($api_url);
    if (is_wp_error($response)) {
        return '<p>書籍情報を取得できませんでした。</p>';
    }

    $body = wp_remote_retrieve_body($response);
    $xml = simplexml_load_string($body);

    if (!$xml || !$xml->channel->item) {
        return '<p>書籍情報が見つかりませんでした。</p>';
    }

    $item = $xml->channel->item;

    // データ取得
    $title = isset($item->title) ? (string)$item->title : '';
    $description = isset($item->description) ? (string)$item->description : '';
    $publisher = isset($item->children('dc', true)->publisher) ? (array)$item->children('dc', true)->publisher : [];
    $issued = isset($item->children('dcterms', true)->issued) ? (string)$item->children('dcterms', true)->issued : '';
    $extent = isset($item->children('dc', true)->extent) ? (string)$item->children('dc', true)->extent : '';
    $guid = isset($item->guid) ? (string)$item->guid : '';

    // 書影が取得可能かチェック
    $cover_response = wp_remote_get($thumbnail_url);
    $has_cover = !is_wp_error($cover_response) && wp_remote_retrieve_response_code($cover_response) === 200;

    // 著者抽出
    preg_match('/<li>責任表示:(.+?)<\/li>/', $description, $author_matches);
    $author = isset($author_matches[1]) ? $author_matches[1] : '';

    // ページ数の表示条件
    $show_extent = strpos($extent, 'p') !== false;

    // HTML生成
    ob_start();
    ?>
	<div class="book-info" style="display: flex; gap: 15px; margin-bottom: 15px; align-items: flex-start;">
    	<?php if ($has_cover): ?>
        <div class="book-cover" style="flex-shrink: 0; margin: 0;">
            <a href="<?php echo esc_url($guid); ?>" target="_blank">
                <img src="<?php echo esc_url($thumbnail_url); ?>" alt="書影" style="max-width: 150px; max-height: 300px; display: block; margin: 0;">
            </a>
        </div>
    	<?php endif; ?>

    	<div class="book-details" style="flex-grow: 1; margin-top: 0;">
        	<p style="font-size: 1.2em; font-weight: bold; margin: 0;">
            	<a href="<?php echo esc_url($guid); ?>" target="_blank" style="text-decoration: none; color: inherit;">
                『<?php echo esc_html($title); ?>』
            	</a>
        	</p>
        	<p style="font-size: 1.1em; font-weight: bold; margin: 5px 0;"><?php echo esc_html($author); ?></p>
        	<p style="margin: 0;"><?php echo esc_html(implode(', ', $publisher)); ?></p>
        	<p style="margin: 5px 0;"><?php if ($issued): ?>【出版】<?php echo esc_html($issued); ?><?php endif; ?></p>
        	<p style="margin: 5px 0;"><?php if ($show_extent): ?>【頁数】<?php echo esc_html($extent); ?><?php endif; ?></p>
        	<p style="font-size: 0.8em; color: gray; margin-top: 10px;">書籍情報は、国立国会図書館サーチのAPI(書影データ提供機関:出版情報登録センター)に由来します。</p>
    	</div>
	</div>

    <?php
    return ob_get_clean();
}
?>

つくづく、すごい時代になったものです。

以下、Google Books APIと国立国会図書館サーチAPIの両方で(今のところ)データを一そろい取得できるタイトルで、表示を比べてみます。

『 昭和16年夏の敗戦』
猪瀬直樹

【出版】 2010-06【頁数】 283
緒戦、奇襲攻撃で勝利するが、国力の差から劣勢となり敗戦に至る…。日米開戦直前の夏、総力戦研究所の若手エリートたちがシミュレーションを重ねて出した戦争の経過は、実際とほぼ同じだった!知られざる実話をもとに日本が“無謀な戦争”に突入したプロセスを描き、意思決定のあるべき姿を示す。
Powered by GoogleGoogle ブックスのAPIを利用しています。

『昭和16年夏の敗戦』

猪瀬直樹 著

中央公論新社

【出版】2010.6

【頁数】283p

書籍情報は、国立国会図書館サーチのAPI(書影データ提供機関:出版情報登録センター)に由来します。

Google Books APIの方では取得できる「本の概要」については、国立国会図書館サーチAPIの方にはそもそもデータが含まれていません。なので、まともに表示できるのであれば、Google Books APIの方が好きなのですが、そもそもまともに表示できないことが、ますます増えてしまったので、このサイトで表示している書籍データも、国立国会図書館サーチのものに差し替える作業を進めていこうと思います。

ちょっとかじっているだけの素人が一日でプラグインを開発できる時代が来るなんて、AIによるプログラミングのハードルの下がりっぷりは凄まじいです。

それ以上にびっくりしたのが、最近のChatGPTが、
「試みましたが、失敗しました。」と言うことです。

こういうのって、AIは適当なことを言って、それなりにうまくできた風に装うイメージだったのですが、少なくともプログラミングにおいては、自分で自分の失敗を認められるんですね。かなりの衝撃を受けました。AIに“正しさ”は分からなくとも、“プログラムしたコードがあきらかに動かない”ことは、AIにもわかるってことなのでしょうか。

コメント

タイトルとURLをコピーしました