エイエイレトリック

なぐりがき

BeautifulsoupでXMLからテキスト取得

前回記事 国立国会図書館サーチの検索API(SRU)を使うの続き。

PythonのBeautifulsoupを使って、国立国会図書館APIから取得したXMLからタイトル情報を取得する。

バージョン情報

Python 3.7.3

beautifulsoup4 4.8.0

lxml 4.4.1

requests 2.22.0

Pythonapiの値を受け取る

Pythonapiの結果の受け取る方法は色々あるが、今回は簡単に使える requestsを利用する。

引数param でパラメータを渡してget()する。

前回に引き続き、ということで コードウェイナー・スミス の著作を検索してみる。 パラメータの意味などは前回のブログをみてください。

import requests

base = 'http://iss.ndl.go.jp/api/sru'
payload = {
    'operation': 'searchRetrieve'
    , 'recordSchema': 'dcndl'
    , 'onlyBib': 'true'
    , 'maximumRecords': '20'
    , 'query': '''creator exact "コードウェイナー・スミス 著"'''
}

r = requests.get(base, params=payload)

Beautifulsoupでパース

受け取ったXMLBeautifulsoup でパースする。

from bs4 import BeautifulSoup
soup = BeautifulSoup(r.text, 'lxml')

recorddata タグに検索結果の情報があるのでこのタグをfind_all()すれば良い。

ちなみに、 recorddata の中身はRDFDublin Core 形式になっている。 この時点(上記の soup )では、中身のRDFはパースされていないので、 取得したレコードをもう一回 Beautifulsoupでパースする必要がある。

rsoup = soup.records.find('recorddata')
record_soup = BeautifulSoup(rsoup, 'lxml')

XMLのなかに違うXML形式のデータという構造が気持ち悪いと思ったのだが、 そもそも国立国会図書館の情報はDublin Coreで記述されおり、 その情報を集約する形式がXMLなだけなので、仕方ない(多分)。

Dublin coreから情報を取得

Dublin coreについて、詳しく調べてみると 「国立国会図書館ダブリンコアメタデータ記述(DC-NDL)」という独自(?) の記述であることがわかった。 このリンクの定義書などから、欲しい情報がどのタグで記述されているかわかる。

今回は短編集と収録作品タイトルを取得したいので調べたところ以下の通りだった。

  • 書籍自体のタイトル
    • dc:titlerdf:descriptionrdf:value に記述
  • 収録作品
    • dcndl:partinformationrdf:descriptiondcterms:title に記述

つまり、 rdf:value タグと dcterms:titlefind() すれば良い。

階層構造を踏まえてタグの中身のテキストを取得したいのだが、 stackoverflowの python - How can I access namespaced XML elements using BeautifulSoup? - Stack Overflow を読む限り、コロンが含まれたタグは tag.dc:title のように直接アクセスできない様子。

なので find('a:hoge').find('b:hoo') でつなげ、その結果をテキストとして取得する。

書籍のタイトル

rsoup.find('dc:title').find('rdf:description').find('rdf:value').text

収録作品のタイトル

for rs in rsoup.find_all('dcndl:partinformation'):
    print(rs.find('rdf:description').find('dcterms:title').text)

調べたところ、RDF用のPythonライブラリ(rdflib 4.2.2 — rdflib 4.2.2 documentation) があるみたいなので、今後はこちらを使った方が良さそう。

結果

上記のコードをまとめた結果をgistに挙げた。

書籍タイトルと収録作品タイトルの辞書型にまとめている。

出力結果はこんな感じ。

アルファ・ラルファ大通り, ['クラウン・タウンの死婦人', '老いた大地の底で', '酔いどれ船', 'ママ・ヒットンのかわゆいキットンたち', 'アルファ・ラルファ大通り', '帰らぬク・メルのバラッド', 'シェイヨルという名の星']
三惑星の探求, ['宝石の惑星', '嵐の惑星', '砂の惑星', '三人、約束の星へ', '太陽なき海に沈む', '第81Q戦争〈オリジナル版〉', '西洋科学はすばらしい', 'ナンシー', '達磨大師の横笛', 'アンガーヘルム', '親友たち']

現状ではハードコーディングしているので、色々使えるように変更していきたい。

あと、RDFLibも使ってみようと思います。