PHPで楽天ブックスAPIを使って書籍検索

(1/1)
楽天ウェブサービスは、楽天市場の販売情報などを提供するAPI群で、アフィリエイトで利用することを想定してつくられている。
今回は、その中から楽天ブックスが販売する書籍の検索ができる楽天ブックス書籍検索APIを利用し、書名、著者名またはISBNコードから書籍情報を取り出すプログラムを作ってみることにする。

(2021年10月24日)PHP8対応,リファラ・チェック改良など

サンプル・プログラムの実行例

PHPで楽天ブックスAPIを使って書籍検索

サンプル・プログラム

圧縮ファイルの内容
searchBook.phpサンプル・プログラム本体。
pahooRakuten.php楽天ウェブサービスに関わるクラス pahooRakuten。
使い方は「PHPで最寄りのネットができるホテルを検索する」などを参照。include_path が通ったディレクトリに配置すること。

楽天ブックス書籍検索API

楽天ブックス書籍検索APIは、楽天ブックスで販売されている書籍の情報を取得することが可能なAPIである。書籍タイトル、著者名、出版社名、書籍サイズ、ISBNコード、ジャンルIDのいずれかをキーワードにして書籍を検索することができる。
ここでは、書籍タイトルまたはISBNコードを検索キーに使う。
WebAPIのURL
URL
https://app.rakuten.co.jp/services/api/BooksBook/Search/20130522

入力パラメータ
フィールド名 要否 内  容
applicationId 必須 楽天ウェブサービスのアプリケーションID
format 任意 'xml'または'json'
【デフォルト】json
title 書籍タイトル
UTF-8でURLエンコードした文字列。複数キーワードから検索したい場合は、半角スペースで区切る。
author 著者名
UTF-8でURLエンコードした文字列。複数キーワードから検索したい場合は、半角スペースで区切る。
publisherName 出版社名
UTF-8でURLエンコードした文字列。複数キーワードから検索したい場合は、半角スペースで区切る。
size 書籍のサイズ
0:全て
1:単行本
2:文庫
3:新書
4:全集・双書
5:事・辞典
6:図鑑
7:絵本
8:カセット,CDなど
9:コミック
10:ムックその他
isbn ISBNコード(10進数13桁)
booksGenreId 楽天ブックスにおけるジャンルを特定するためのID
hits 任意 1ページあたりの取得件数
1から30までの整数
【デフォルト】30
page 任意 取得ページ
1から100までの整数
【デフォルト】1
availability 任意 在庫状況
0:すべての商品【省略時】
1:在庫あり
2:2~3日以内に発送予定
3:1~2週間以内に発送予定
4:予約受付中
outOfStockFlag 任意 品切れ等購入不可商品表示フラ
0:品切れや販売終了など購入不可の商品は結果に表示させない【省略時】
1:品切れや販売終了など購入不可の商品を結果に表示させる
chirayomiFlag 任意 チラよみフラグ
0:すべての商品【省略時】
1:チラよみ対象商品で絞り込む
sort 任意 ソート
standard:標準【省略時】
sales:売れている
+releaseDate:発売日(古い)
-releaseDate:発売日(新しい)
+itemPrice:価格が安い
-itemPrice:価格が高い
+reviewCount:レビューの件数が少ない
-reviewCount:レビューの件数が多い
carrier 任意 PC用の情報を返すのか、モバイル用の情報を返すのかを選択
PC: 0【省略時】
mobile: 1
genreInformationFlag 任意 ジャンルごとの商品数取得フラグ
0 :ジャンルごとの商品数の情報を取得しない【省略時】
1 :ジャンルごとの商品数の情報を取得する
★タイトル、著者名、出版社名、書籍のサイズ、ISBNコード、楽天ブックスジャンルIDのいずれかが指定されていることが必須。
応答データ(xml) root count 検索結果の総商品数 page 現在のページ番号 first 検索結果の何件目からか last 検索結果の何件目までか hits 一度に返却する商品数 carrier PC=0 or mobile=1 pageCount 総ページ数 Items Item title 書籍タイトル titleKana 書籍タイトル カナ subTitle 書籍サブタイトル subTitleKana 書籍サブタイトル カナ seriesName 叢書名 seriesNameKana 叢書名カナ contents 多巻物収録内容 contentsKana 多巻物収録内容カナ author 著者名 authorKana 著者名カナ publisherName 出版社名 size 書籍のサイズ isbn ISBNコード itemCaption 商品説明文 salesDate 発売日 itemPrice 税込み販売価格 listPrice 定価 discountRate 割引率 discountPrice 割引価格 itemUrl 商品URL affiliateUrl アフィリエイトURL smallImageUrl 商品画像 64x64URL mediumImageUrl 商品画像 128x128URL largeImageUrl 商品画像 200x200URL chirayomiUrl チラよみURL availability 在庫状況 postageFlag 送料フラグ limitedFlag 限定フラグ reviewCount レビュー件数 reviewAverage レビュー平均 booksGenreID 楽天ブックスジャンルID
エラー内容はHTTPステータスコードとレスポンスボディから判断する。

準備:pahooRakuten クラス

0016: // 楽天ウェブサービス・クラス ===============================================
0017: class pahooRakuten {
0018:     var $error;          //エラーフラグ
0019:     var $hits;           //検索ヒット件数
0020:     var $webapi;     //直前に呼び出したWebAPI URL
0021: 
0022:     //楽天ウェブサービス
0023:     //https://www.pahoo.org/e-soul/webtech/php06/php06-01-02.shtm#Rakuten参照
0024:     var $APPLICATIONID      = '*******************';    //アプリID
0025:     var $APPLICATION_SECRET = '****************';       //シークレット
0026:     var $AFFILIATEID        = '*******************';    //アフィリエイトID

楽天トラベルのホテル検索、楽天市場の商品検索など、楽天ウェブサービスを利用するために、クラスファイル "pahooRakuten.php" を使用する。組み込み関数  require_once  を使って読めるディレクトリに配置する。ディレクトリは、設定ファイル php.ini に記述されているオプション設定 include_path に設定しておく。
クラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」を参照されたい。

楽天ウェブサービスには、アプリIDアフィリエイトID が必要で、その入手方法は「楽天ウェブサービス - WebAPIの登録方法」を参照されたい。

解説:WebAPIコール

0075: /**
0076:  * WebAPIを呼び出して応答データを取得する(https用)
0077:  * @param   string $urlリスクエストURL
0078:  * @return  string応答データ/FALSE=失敗
0079: */
0080: function callWebAPI($url) {
0081:     $ch = curl_init($url);
0082:     curl_setopt($chCURLOPT_HEADERFALSE);
0083:     curl_setopt($chCURLOPT_RETURNTRANSFERTRUE);
0084:     curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE); //サーバ証明書検証をスキップ
0085:     curl_setopt($chCURLOPT_SSL_VERIFYHOSTFALSE); //  〃
0086:     $result = curl_exec($ch);
0087:     curl_close($ch);
0088: 
0089:     return $result;
0090: }

WebAPIはhttpsプロトコルであるため、ユーザー関数 callWebAPI のように cURL 関数を用いて呼び出している。このあたりについては「PHPセキュリティ対策:SSL通信を行う」で解説している。

解説:応答データの扱い

0155: /**
0156:  * 楽天ブックスAPIで書籍検索
0157:  * @param   string $query  ISBN番号または書籍名
0158:  * @param   string $author 著者名
0159:  * @param   array  $items  検索結果を格納する配列
0160:  * @param   string $sort   ソート(省略時:standard)
0161:  * @return  ヒットした件数/FALSE:検索に失敗
0162: */
0163: function searchBooks($query$author, &$items$sort='standard') {
0164:     $url = $this->searchBooksURL($query$author$sort);
0165:     if (($res = $this->callWebAPI($url)) == FALSE) {
0166:         $this->error  = TRUE;
0167:         $this->errmsg = 'WebAPI呼び出しに失敗';
0168:         return FALSE;
0169:     }
0170:     $this->webapi = $url;
0171: 
0172: //PHP4用; DOM XML利用
0173:     if ($this->isphp5over() == FALSE) {
0174:         if (($dom = domxml_open_mem($res)) == NULLreturn FALSE;
0175:         $root = $dom->get_elements_by_tagname('root');
0176: 
0177:         //レスポンス・チェック
0178:         $count = $root[0]->get_elements_by_tagname('count');
0179:         $cnt = $count[0]->get_content();
0180:         if ($cnt <= 0) { //ヒットせず
0181:             $this->error  = TRUE;
0182:             $this->errmsg = '検索結果なし';
0183:             return FALSE;
0184:         }
0185:         //書籍情報取りだし
0186:         $obj = $root[0]->get_elements_by_tagname('Items');
0187:         $obj = $obj[0]->get_elements_by_tagname('Item');
0188:         $cnt = 1;
0189:         foreach ($obj as $val) {
0190:             foreach ($this->RakutenBooksItems as $name) {
0191:                 $node = $val->get_elements_by_tagname($name);
0192:                 if ($node != NULL) {
0193:                     $items[$cnt][$name] = $node[0]->get_content();
0194:                 }
0195:             }
0196:             $items[$cnt]['title'] = preg_replace("/([あ-ん|ア-ン])-/ui", "$1ー", $items[$cnt]['title']);
0197:             $items[$cnt]['titleKana'] = preg_replace("/([あ-ん|ア-ン])-/ui", "$1ー", $items[$cnt]['titleKana']);
0198:             $cnt++;
0199:         }
0200: 
0201: //PHP5用; SimpleXML利用
0202:     } else {
0203:         $xml = simplexml_load_string($res);
0204:         //レスポンス・チェック
0205:         $count = (int)$xml->count;
0206:         if ($count <= 0) {   //ヒットせず
0207:             $this->error  = TRUE;
0208:             $this->errmsg = '検索結果なし';
0209:             return FALSE;
0210:         }
0211:         $obj = $xml->Items->Item;
0212:         $cnt = 1;
0213:         foreach ($obj as $node) {
0214:             foreach ($this->RakutenBooksItems as $name) {
0215:                 if (isset($node->$name)) {
0216:                     $items[$cnt][$name] = (string)$node->$name;
0217:                 }
0218:             }
0219:             $items[$cnt]['title'] = preg_replace("/([あ-ん|ア-ン])-/ui", "$1ー", $items[$cnt]['title']);
0220:             $items[$cnt]['titleKana'] = preg_replace("/([あ-ん|ア-ン])-/ui", "$1ー", $items[$cnt]['titleKana']);
0221:             $cnt++;
0222:         }
0223:     }
0224:     $this->hits = $cnt - 1;
0225: 
0226:     return $this->hits;
0227: }

応答データの要素が多いので、取得したい要素を $RakutenBooksItems にあらかじめ定義しておき、ユーザー関数 searchBooks の中で付き合わせながら配列$items に格納していく。

参考サイト

(この項おわり)
header