ISBNを使ってGoogle BooksとOpenDB APIからNotionに書籍情報を自動的に取り込む

目的

  • ISBNから、文献情報に必要な書籍情報をNotionのデーターベースに取り込めるようにしたい。
  • 環境は、M1 Mac、macOS (14.0 (23A344)) である。ターミナルにて、Python3 を用いたい。

経緯と注意

  • 今のところ,上記を行うことのできる有用なツールが存在しない。
  • 著者はプログラミングに強くないので,不完全なものである。

書籍情報の取り込みの自動化

仕様

  • OpenDBから,タイトルを入手すると「名字,名前」となってしまう。情報を所得した後に「,」を抜いても良いのだが,今後 Google Books から更に情報を抜きたくなったときを想定し,2つのAPIを用いている。Google Books には出版社情報は無いはず。つまり,良いとこ取りしたいのである (他でこういった仕様が見つからない)。
  • 出版年については,OpenBDでは「年月」で取得される。月は必要なかったため取り除いている。
  • 著者は,複数名存在した場合であっても取り込みを行うことができる。マルチセレクトをプロパティとして設定している。
  • ISBNは,「, 」(半角カンマ+半角スペース) で区切り,複数件同時に取り込みを行こともできる。
  • その他,PythonのことやNotion API の扱いについては,以下のページや他のサイトをあたって欲しい。参考: https://yamanori.net/?p=126&preview=true
import requests

GOOGLE_BOOKS_API = 'https://www.googleapis.com/books/v1/volumes?q=isbn:'
OPENBD_API = 'https://api.openbd.jp/v1/get'
NOTION_API = 'https://api.notion.com/v1/pages'
NOTION_DATABASE_ID = '<データベースIDを記入>'
NOTION_SECRET = '<トークンを記入>'

def extract_numeric(value):
    return int(value) if value.isdigit() else None

def extract_year(pubdate):
    return extract_numeric(pubdate[:4]) if pubdate else None

def get_book_info(isbn):
    try:
        # Google Books APIからデータを取得
        google_response = requests.get(GOOGLE_BOOKS_API + isbn)
        google_response.raise_for_status()
        google_data = google_response.json().get("items", [{}])[0].get("volumeInfo", {})

        # OpenBD APIからデータを取得
        openbd_response = requests.get(OPENBD_API, params={"isbn": isbn})
        openbd_data = openbd_response.json()[0].get("summary", {})

        # 取得したデータを結合
        combined_info = {**google_data, **openbd_data}

        # 著者データを整形
        authors_data = [{"name": author} for author in combined_info.get('authors', [])]

        # "Authors" プロパティの作成
        authors_property = {"multi_select": [{"name": author["name"]} for author in authors_data]}

        # Notion ページのプロパティを作成
        notion_properties = {
            "Title": {"title": [{"text": {"content": combined_info.get("title")}}]},
            "Authors": authors_property,
            "ISBN": {"number": extract_numeric(combined_info.get("isbn"))},
            "Pubdate": {"number": extract_year(combined_info.get("pubdate"))},
            "Publisher": {"select": {"name": combined_info.get("publisher")}},
            "Volume": {"number": extract_numeric(combined_info.get("volume"))},
            "Series": {"rich_text": [{"text": {"content": combined_info.get("series", "")}}]}
        }

        # Noneの値をフィルタリング
        filtered_properties = {key: value for key, value in notion_properties.items() if value is not None}

        # Notion ページにデータを送信
        send_to_notion(filtered_properties)

    except requests.exceptions.RequestException as e:
        print(f"ISBN: {isbn} のデータを取得中にエラーが発生しました: {e}")

def send_to_notion(properties):
    # Notionにデータを送信する関数の実装
    headers = {
        'Authorization': f'Bearer {NOTION_SECRET}',
        'Content-Type': 'application/json',
        'Notion-Version': '2022-06-28'
    }
    data = {
        "parent": {"database_id": NOTION_DATABASE_ID},
        "properties": properties
    }
    
    # Notion ページにデータを送信
    notion_response = requests.post(NOTION_API, headers=headers, json=data)
    
    # エラーメッセージの詳細を表示
    # print(notion_response.status_code)
    # print(notion_response.text)
    
    notion_response.raise_for_status()

if __name__ == "__main__":
    isbns = input("ISBN>>>")
    isbns_list = [isbn.strip() for isbn in isbns.split(', ')]
    
    for isbn in isbns_list:
        get_book_info(isbn)