2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

国立国会図書館の検索用APIを利用してISBNから書籍情報を取得する(OpenSearch)

2
Last updated at Posted at 2025-02-18

1.国立国会図書館APIについて

今回はpythonと検索用API(opensearch)を用いて書籍情報を取得します。

ISBNを用いて一致する書籍を探し、タイトル・著者名などの書籍情報を取得し、使いやすく整形して辞書型で返す関数型のプログラムを作成しました。

以前にも似たような記事を書いていたのですが、やや処理が冗長だったのとデータ構造が整理できてなかったので、再度記事を書きなおしました。

以下のページなどを参考にしています。

2.データ取得の実例

国立国会図書館のAPIはレスポンスをXML形式で返してくるので、これをpythonで扱いやすい辞書型に変換するため、xmltodictを利用しています。

辞書に変換されたXMLファイルは構造がやや入れ子になっているので、使う情報を自分なりに整理しています。
ひとまず自分が利用したい情報を取るにはどの階層のデータにアクセスするかだけを考えてデータを取得しています。

pprintはここでは結果の確認のために使用しています。どのデータが取得できるかを確認してみてください。

example.py
import requests
import xmltodict
import pprint

# ISBNを使って書誌情報を取得
def fetch_book_info(isbn):
    # NDLサーチAPI(国立国会図書館の説明を参照)
    base_url = "https://iss.ndl.go.jp/api/opensearch"
    
    # APIリクエストのパラメータを設定
    params = {
        'isbn': isbn,
        'format': 'xml'
    }

    # リクエストを取得
    response = requests.get(base_url, params=params)

    # XMLを辞書型に変換
    book_info = xmltodict.parse(response.text)

    # 入れ子になった辞書型を整理し、必要と思われる情報のみ取得
    book_dict = {
    "author": book_info['rss']['channel']['item']['author'], # 著者
    "category": book_info['rss']['channel']['item']['category'], # カテゴリ
    "creator": book_info['rss']['channel']['item']['dc:creator'], # 作者
    "publication_year": book_info['rss']['channel']['item']['dc:date']['#text'], # 発行年
    "description": book_info['rss']['channel']['item']['dc:description'], # 説明
    "pages": book_info['rss']['channel']['item']['dc:extent'], # ページ数
    "isbn_data": book_info['rss']['channel']['item']['dc:identifier'][0]['#text'], #ISBN
    "publisher": book_info['rss']['channel']['item']['dc:publisher'], # 出版社
    "call_number": book_info['rss']['channel']['item']['dc:subject'][1]['#text'], # 請求記号
    "title": book_info['rss']['channel']['item']['dc:title'], #タイトル
    "author_kana": book_info['rss']['channel']['item']['dcndl:creatorTranscription'], # 作者カナ表記
    "price": book_info['rss']['channel']['item']['dcndl:price'], # 価格
    "series_title": book_info['rss']['channel']['item']['dcndl:seriesTitle'], # シリーズ名
    "series_title_kana": book_info['rss']['channel']['item']['dcndl:seriesTitleTranscription'], # シリーズ名カナ表記
    "title_kana": book_info['rss']['channel']['item']['dcndl:titleTranscription'] #タイトルカナ表記
    }

    """ 変数に代入する場合の例
    author = book_info['rss']['channel']['item']['author'] # 著者
    category = book_info['rss']['channel']['item']['category'] # カテゴリ
    creator = book_info['rss']['channel']['item']['dc:creator'] # 作者
    publication_year = book_info['rss']['channel']['item']['dc:date']['#text'] # 発行年
    description = book_info['rss']['channel']['item']['dc:description'] # 説明
    pages = book_info['rss']['channel']['item']['dc:extent'] # ページ数
    isbn_data = book_info['rss']['channel']['item']['dc:identifier'][0]['#text'] #ISBN
    publisher = book_info['rss']['channel']['item']['dc:publisher'] # 出版社
    call_number = book_info['rss']['channel']['item']['dc:subject'][1]['#text'] # 請求記号
    title = book_info['rss']['channel']['item']['dc:title'] #タイトル
    author_kana = book_info['rss']['channel']['item']['dcndl:creatorTranscription'] # 作者カナ表記
    price = book_info['rss']['channel']['item']['dcndl:price'] # 価格
    series_title = book_info['rss']['channel']['item']['dcndl:seriesTitle'] # シリーズ名
    series_title_kana = book_info['rss']['channel']['item']['dcndl:seriesTitleTranscription'] # シリーズ名カナ表記
    title_kana = book_info['rss']['channel']['item']['dcndl:titleTranscription'] #タイトルカナ表記
    """

    return book_dict

# ISBNを指定して情報を取得
isbn = '9784043898039' 
d = fetch_book_info(isbn)

# 結果を整形して表示
pprint.pprint(d)

""" 結果
{'author': '有川, 浩, 1972-,有川浩 [著]',
 'author_kana': 'アリカワ, ヒロ, 1972-',
 'call_number': '913.6',
 'category': ['図書', ''],
 'creator': '有川, 浩, 1972-',
 'description': ['メディアワークス2007年刊の加筆、訂正', '2010'],
 'isbn_data': '978-4-04-389803-9',
 'pages': '444p',
 'price': '667円',
 'publication_year': '2010',
 'publisher': ['角川書店', '角川グループパブリッシング (発売)'],
 'series_title': '角川文庫 ; 16082',
 'series_title_kana': 'カドカワ ブンコ ; 16082',
 'title': '塩の街',
 'title_kana': 'シオ ノ マチ'}
"""

3.リクエストを送る時の注意点

ここまでくればjsonにしてみたり、isbnのリストをループさせて書籍情報を連続で取得したりできると思います。

なお、ループ処理を行う場合は下記の留意事項を遵守する必要があります。

基本的には、単一のリクエストを適切な時間間隔を設け、サーバーに不可をかけないようにリクエストするのが望ましいでしょう。

example.py
    # リクエスト取得部分をコメントアウト
    # response = requests.get(APIのURL, params=APIリクエスト用パラメータ)

    # with open('response_data.txt', 'w', encoding='utf-8') as file:
    #    file.write(response.text)  # テキストデータを保存

    # 保存済みのテキストファイルを読み込む
    with open('response_data.txt', 'r', encoding='utf-8') as file:
        response = file.read()

    # XMLを辞書型に変換
    book_info = xmltodict.parse(response) # 保存時にテキストとして保存したので.textをはずす

4.XMLデータの複雑さ

もともとのXMLデータの階層が複雑なため、変換された辞書型のデータも複雑になっています。

以下は一部を実行結果の出力を一部抜粋したものです。

example.py
"isbn_data": book_info['rss']['channel']['item']['dc:identifier'][0]['#text'], #ISBN

['dc:identifier']の下層に[0]という配列が入っていると思います。

本は、旧版と新装版の違いや出版社の変更などによって、同じ本でもISBNが違ったりすることがあるようです。もしかしたら、本ごとに複数のISBNを格納する可能性があるという前提でデータ構造が設計されているのかもしれませんね。

このように本によってデータ構造は様々なので、思ったとおりに書誌情報の取得ができない場合もあります。

最後に、実行結果の例を示します。

example.py
# 実行結果の例
{'rss': {'@version': '2.0',
         '@xmlns:dc': 'http://purl.org/dc/elements/1.1/',
         '@xmlns:dcmitype': 'http://purl.org/dc/dcmitype/',
         '@xmlns:dcndl': 'http://ndl.go.jp/dcndl/terms/',
         '@xmlns:dcterms': 'http://purl.org/dc/terms/',
         '@xmlns:openSearch': 'http://a9.com/-/spec/opensearchrss/1.0/',
         '@xmlns:rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
         '@xmlns:rdfs': 'http://www.w3.org/2000/01/rdf-schema#',
         '@xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
         'channel': {'description': 'Search results for isbn=9784043898039 '
                                    'format=xml',
                     'item': {'author': '有川, 浩, 1972-,有川浩 [著]',
                              'category': ['図書', ''],
                              'dc:creator': '有川, 浩, 1972-',
                              'dc:date': {'#text': '2010',
                                          '@xsi:type': 'dcterms:W3CDTF'},
                              'dc:description': ['メディアワークス2007年刊の加筆、訂正',
                                                 '2010'],
                              'dc:extent': '444p',
                              'dc:identifier': [{'#text': '978-4-04-389803-9',
                                                 '@xsi:type': 'dcndl:ISBN'},
                                                {'#text': '000010905866',
                                                 '@xsi:type': 'dcndl:NDLBibID'},
                                                {'#text': '21795827',
                                                 '@xsi:type': 'dcndl:JPNO'},
                                                {'#text': '104998700',
                                                 '@xsi:type': 'dcndl:NSMARCNO'}],
                              'dc:publisher': ['角川書店', '角川グループパブリッシング (発売)'],
                              'dc:subject': [{'#text': 'KH67',
                                              '@xsi:type': 'dcndl:NDLC'},
                                             {'#text': '913.6',
                                              '@xsi:type': 'dcndl:NDC9'}],
                              'dc:title': '塩の街',
                              'dcndl:creatorTranscription': 'アリカワ, ヒロ, 1972-',
                              'dcndl:price': '667円',
                              'dcndl:publicationPlace': 'JP',
                              'dcndl:seriesTitle': '角川文庫 ; 16082',
                              'dcndl:seriesTitleTranscription': 'カドカワ ブンコ ; '
                                                                '16082',
                              'dcndl:titleTranscription': 'シオ ノ マチ',
                              'dcterms:issued': '2010.1',
                              'description': '<p>角川書店,2010,978-4-04-389803-9<p><ul><li>タイトル:塩の街</li><li>タイトル(読み):シオ '
                                             'ノ マチ</li><li>責任表示:有川浩 '
                                             '[著]</li><li>シリーズ名:角川文庫 ; '
                                             '16082</li><li>シリーズ名(読み):カドカワ ブンコ '
                                             '; '
                                             '16082</li><li>NDC(9):913.6</li></ul>',
                              'guid': {'#text': 'https://ndlsearch.ndl.go.jp/books/R100000002-I000010905866',
                                       '@isPermaLink': 'true'},
                              'link': 'https://ndlsearch.ndl.go.jp/books/R100000002-I000010905866',
                              'pubDate': 'Tue, 9 Nov 2021 01:03:52 +0900',
                              'rdfs:seeAlso': [{'@rdf:resource': 'https://www.library.city.sapporo.jp/licsxp-opac/WOpacMsgNewListToTifTilDetailAction.do?tilcod=1008000245880'},
                                               {'@rdf:resource': 'https://www.library.city.sapporo.jp/licsxp-opac/WOpacMsgNewListToTifTilDetailAction.do?tilcod=1008001179073'},
                                               {'@rdf:resource': 'http://kensaku.lib.pref.tochigi.lg.jp/winj/opac/switch-detail-iccap.do?bibid=1101626332'},
                                               {'@rdf:resource': 'https://www.lib.city.saitama.jp/bookdetail?num=2280410&ctg=1'},
                                               {'@rdf:resource': 'https://www.lib.city.saitama.jp/bookdetail?num=2707391&ctg=1'},
                                               {'@rdf:resource': 'https://www.library.city.chiba.jp/licsxp-opac/WOpacTifSchCmpdDispAction.do'},
                                               {'@rdf:resource': 'https://opac.lib.city.yokohama.lg.jp/winj/opac/switch-detail-iccap.do?bibid=1110004412'},
                                               {'@rdf:resource': 'https://www.library.city.kawasaki.jp/bookdetail?num=1938589&ctg=1'},
                                               {'@rdf:resource': 'https://www.lib.sagamihara.kanagawa.jp/TOSHOW/asp/WwShousaiKen.aspx?FCode=1815838'},
                                               {'@rdf:resource': 'https://www.library.pref.ishikawa.lg.jp/wo/opc_srh/srh_detail/1000001057582/'},
                                               {'@rdf:resource': 'https://www.library-archives.pref.fukui.lg.jp/wo/opc_srh/srh_detail/1104898915/'},
                                               {'@rdf:resource': 'https://www.library.pref.nagano.jp/licsxp-opac/WOpacMsgNewListToTifTilDetailAction.do?tilcod=1000000307777'},
                                               {'@rdf:resource': 'https://www.toshokan.city.shizuoka.jp/licsxp-opac/WOpacMsgNewListToTifTilDetailAction.do?tilcod=1001101673266'},
                                               {'@rdf:resource': 'https://www.library.city.nagoya.jp/licsxp-opac/WOpacMsgNewListToTifTilDetailAction.do?tilcod=1000910091766'},
                                               {'@rdf:resource': 'https://www.library.city.nagoya.jp/licsxp-opac/WOpacMsgNewListToTifTilDetailAction.do?tilcod=1001710028790'},
                                               {'@rdf:resource': 'https://web.oml.city.osaka.lg.jp/webopac_i_ja/0012007757'},
                                               {'@rdf:resource': 'https://web.oml.city.osaka.lg.jp/webopac_i_ja/0014336116'},
                                               {'@rdf:resource': 'https://www.lib-sakai.jp/licsxp-opac/WOpacMsgNewListToTifTilDetailAction.do?tilcod=1001000514569'},
                                               {'@rdf:resource': 'https://www.lib-sakai.jp/licsxp-opac/WOpacMsgNewListToTifTilDetailAction.do?tilcod=1007000747377'},
                                               {'@rdf:resource': 'http://www.lib.wakayama-c.ed.jp/winj/opac/switch-detail-iccap.do?bibid=1102121547'},
                                               {'@rdf:resource': 'https://www2.library.pref.shimane.lg.jp/opac/switch-detail-iccap.do?bibid=1110066873'},
                                               {'@rdf:resource': 'https://opac.libnet.pref.okayama.jp/licsxp-opac/WOpacMsgNewListToTifTilDetailAction.do?tilcod=1009812133453'},
                                               {'@rdf:resource': 'http://www.library.city.hiroshima.jp/winj/opac/switch-detail-iccap.do?bibid=1103163814'},
                                               {'@rdf:resource': 'https://www.library.pref.kagawa.lg.jp/winj/opac/switch-detail-iccap.do?bibid=1100336168'},
                                               {'@rdf:resource': 'https://www.ehimetosyokan.jp/winj/opac/switch-detail-iccap.do?bibid=1101015440'},
                                               {'@rdf:resource': 'https://opac.toshokan.city.fukuoka.lg.jp/licsxp-opac/WOpacTifSchCmpdDispAction.do'},
                                               {'@rdf:resource': 'https://opac.miraionlibrary.jp/licsxp-opac/WOpacMsgNewListToTifTilDetailAction.do?tilcod=1000000832192'},
                                               {'@rdf:resource': 'https://library.pref.oita.jp/winj/opac/switch-detail-iccap.do?bibid=1100493998'},
                                               {'@rdf:resource': 'https://www.lib.pref.miyazaki.lg.jp/winj/opac/switch-detail-iccap.do?bibid=1101550275'},
                                               {'@rdf:resource': 'https://www2.library.pref.kagoshima.jp/kento/opac/switch-detail-iccap.do?bibid=1110005350'},
                                               {'@rdf:resource': 'https://ndlsearch.ndl.go.jp/books/R100000002-I000010905866'},
                                               {'@rdf:resource': 'https://library.sapie.or.jp/cgi-bin/CN1MN1?S00101=J00DTL04&S00222=1762615'},
                                               {'@rdf:resource': 'https://library.sapie.or.jp/cgi-bin/CN1MN1?S00101=J00DTL04&S00222=3788837'},
                                               {'@rdf:resource': 'https://www.kanabun.or.jp/CARIN/CARINOPACLINK.HTM?ID=B00192023'},
                                               {'@rdf:resource': 'https://ci.nii.ac.jp/ncid/BB0102421X'},
                                               {'@rdf:resource': 'https://www.books.or.jp/book-details/04389803A00498100000'},
                                               {'@rdf:resource': 'https://www.books.or.jp/book-details/9784043898039'}],
                              'title': '塩の街'},
    

5.最後に

何かの足しになれば幸いです。

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?