質問するログイン新規登録

Q&A

解決済

1回答

176閲覧

楽天APIを使用して楽天ブックスから書籍のデータを取得したい。

3chomenanigashi

総合スコア15

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2026/02/26 06:09

0

1

実現したいこと

GASもしくはPython(Colab、JupyterNotebook)で実現したいと思っています。
GoogleスプレッドシートのISBNリストから、該当書籍のタイトル、著者名、出版社、書影等のデータを取得したいです。

発生している問題・分からないこと

Geminiにコードを何度も書いてもらいましたが、おそらく楽天APIの仕様変更のため403エラーが出たり取得できなかったりでつまづいています。
(旧APIのアプリIDがあれば解決するらしいですが、所持しておりません)

該当のソースコード

google

1/** 2 * 楽天市場商品検索APIを代用して書籍情報を取得する 3 * (新UUID形式でも認証が通る唯一の安定ルートです) 4 */ 5function updateBookDetailsFromISBN() { 6 const APP_ID = '自分のアプリケーションID'; 7 const AFFILIATE_ID = '自分のアフィリエイトID'; 8 9 const ss = SpreadsheetApp.getActiveSpreadsheet(); 10 const sheet = ss.getSheetByName('TEST'); 11 if (!sheet) return; 12 13 const lastRow = sheet.getLastRow(); 14 if (lastRow < 2) return; 15 const range = sheet.getRange(2, 1, lastRow - 1, 6); 16 const values = range.getValues(); 17 18 for (let i = 0; i < values.length; i++) { 19 let isbn = String(values[i][1]).replace(/-/g, '').trim(); 20 if (!isbn || values[i][0]) continue; 21 22 try { 23 // 楽天市場の商品検索APIを使い、ショップを楽天ブックス(213310)に限定してISBN検索 24 const url = "https://app.rakuten.co.jp/services/api/IchibaItem/Search/20170706" + 25 "?applicationId=" + APP_ID + 26 "&affiliateId=" + AFFILIATE_ID + 27 "&keyword=" + isbn + 28 "&shopCode=book" + // 楽天ブックスに限定 29 "&format=json"; 30 31 const response = UrlFetchApp.fetch(url, { "muteHttpExceptions": true }); 32 const result = JSON.parse(response.getContentText()); 33 34 if (response.getResponseCode() === 200 && result.Items && result.Items.length > 0) { 35 const item = result.Items[0].Item; 36 37 // 取得した商品名からタイトルを抽出 38 sheet.getRange(i + 2, 1).setValue(item.itemName); 39 sheet.getRange(i + 2, 3).setFormula('=IMAGE("' + item.mediumImageUrls[0].imageUrl + '")'); 40 41 // 楽天市場APIには著者名・出版社名が個別項目にないため、商品名から推測するか、 42 // 取得可能な情報をセットします 43 sheet.getRange(i + 2, 5).setValue("楽天ブックス"); 44 sheet.getRange(i + 2, 6).setValue(item.affiliateUrl); 45 46 console.log("取得成功: " + item.itemName); 47 } else { 48 console.warn("ISBN: " + isbn + " で商品が見つかりませんでした。"); 49 } 50 51 Utilities.sleep(1000); 52 } catch (e) { 53 console.error("エラー: " + e.message); 54 } 55 } 56}

Python

1import requests 2import time 3import pandas as pd 4from google.colab import auth 5import gspread 6from google.auth import default 7 8# 1. Googleスプレッドシートの認証 9auth.authenticate_user() 10creds, _ = default() 11gc = gspread.authorize(creds) 12 13# --- 設定情報 (URLとシート名を正確に入力してください) --- 14SPREADSHEET_URL = '自分のスプレッドシートURL' 15SHEET_NAME = 'TEST' 16 17APP_ID = '自分のアプリケーションID' 18AFFILIATE_ID = '自分のアフィリエイトID' 19 20# --- 楽天API関連の関数 --- 21 22def fetch_rakuten_book_via_ichiba(isbn, app_id, affiliate_id): 23 """ 24 楽天市場APIを代用して書籍情報を取得する。 25 新UUIDでもURLパラメータ認証が通る安定ルート。 26 """ 27 url = "https://app.rakuten.co.jp/services/api/IchibaItem/Search/20170706" 28 29 params = { 30 "applicationId": app_id, 31 "affiliateId": affiliate_id, 32 "keyword": isbn, 33 "shopCode": "book", # 楽天ブックスに絞り込み 34 "format": "json" 35 } 36 37 try: 38 # このエンドポイント(app.rakuten.co.jp)ならDNSエラーが起きない 39 res = requests.get(url, params=params, timeout=15) 40 41 if res.status_code == 200: 42 result = res.json() 43 if result.get("Items"): 44 item = result["Items"][0]["Item"] 45 # 楽天市場APIの返却値を整理 46 return { 47 "title": item.get("itemName", ""), 48 "largeImageUrl": item.get("mediumImageUrls", [{}])[0].get("imageUrl", ""), 49 "author": "楽天ブックス", # 市場APIでは著者名が分離されていない 50 "publisherName": "楽天ブックス", 51 "affiliateUrl": item.get("affiliateUrl", "") 52 } 53 else: 54 print(f" APIエラー ({res.status_code}): {res.text}") 55 except Exception as e: 56 print(f" 通信エラー: {e}") 57 return None 58 59# --- メイン処理 --- 60 61def main(): 62 try: 63 # スプレッドシートの読み込み 64 sh = gc.open_by_url(SPREADSHEET_URL) 65 worksheet = sh.worksheet(SHEET_NAME) 66 except Exception as e: 67 print(f"スプレッドシート接続エラー: {e}") 68 return 69 70 # 全データを取得してDataFrame化 71 data = worksheet.get_all_values() 72 if len(data) < 2: 73 print("データが見つかりません。") 74 return 75 76 header = data[0] 77 df = pd.DataFrame(data[1:], columns=header) 78 79 print(f"互換モードで処理を開始します... (対象: {len(df)}件)") 80 81 for index, row in df.iterrows(): 82 # カラム名はスプレッドシートの1行目に合わせる 83 isbn = str(row.get('ISBN', '')).replace('-', '').strip() 84 title_exists = row.get('タイトル', '').strip() 85 86 # タイトルが空かつISBNがある場合のみ実行 87 if isbn and not title_exists: 88 print(f"[{index + 2}行目] 検索中: {isbn}") 89 book = fetch_rakuten_book_via_ichiba(isbn, APP_ID, AFFILIATE_ID) 90 91 if book: 92 row_num = index + 2 93 try: 94 # 1行ずつスプレッドシートを更新 95 # A:タイトル(1), C:画像(3), D:著者(4), E:出版社(5), F:リンク(6) 96 worksheet.update_cell(row_num, 1, book['title']) 97 worksheet.update_cell(row_num, 3, f'=IMAGE("{book["largeImageUrl"]}")') 98 worksheet.update_cell(row_num, 4, book['author']) 99 worksheet.update_cell(row_num, 5, book['publisherName']) 100 worksheet.update_cell(row_num, 6, book['affiliateUrl']) 101 print(f" -> 成功: {book['title'][:20]}...") 102 except Exception as e: 103 print(f" -> スプレッドシート更新エラー: {e}") 104 105 # API制限(秒間1リクエスト程度)を考慮して待機 106 time.sleep(1.5) 107 else: 108 print(f" -> 楽天ブックスに商品なし") 109 110 print("\nすべての処理が完了しました。スプレッドシートを確認してください。") 111 112if __name__ == "__main__": 113 main()

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

旧仕様の方法は見つかったが、新仕様での方法が見つからない

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

guest

回答1

0

ベストアンサー

投稿2026/02/26 09:11

yambejp

総合スコア118369

3chomenanigashi

2026/02/26 23:48

回答ありがとうございます。 NDLも含めて代替案として検討します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.29%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問