BeautifulSoupでXMLをパース(解析)加工する – Python

XMLとは?

XMLとは、文書やデータの意味や構造を記述するためのマークアップ言語の一つ。 マークアップ言語とは、「タグ」と呼ばれる特定の文字列で地の文に情報の意味や構造、装飾などを埋め込んでいく言語のことで、XMLはユーザが独自のタグを指定できることから、マークアップ言語を作成するためのメタ言語とも言われる。

https://www.graffe.jp/blog/2911/

一帯何に使うマークアップなのか?という方もいらっしゃるかもしれませんが、よくあるのはAPIでのレスポンスです。

割とよく見る馴染み深いレスポンス形式といえば「JSON」という方も少なくないと思います。

最近ではJSONに押され気味ながらも、まだまだXMLも健在です。

PythonでのXML解析にBeautifulSoupを使ってみる

BeautifulSoupはHTMLのパースというイメージがあるかと思いますが、実はXMLの解析にも使えます。

サンプルはAmazonMWSへのアクセス時にレスポンスとして帰ってくるXMLを使います。

MWS-GetProductCategoriesForASINで取得したXMLです。

どういったソースなのかというと、商品が属するカテゴリノードを示したXMLです。Amazonでは一商品一カテゴリという分類ではなく、複数のカテゴリ分類に属している可能性があり、上記は一商品分のソースで、3つのカテゴリ分類に属しています。

BeautifulSoupにXMLを渡す

まずは解析準備です。

MWSアクセスのコードは省略します。res.contentがXMLの文字列本体だと思ってください。

BeautifulSoupオブジェクトの作成

上記記事でHTMLをパースした時とsoupオブジェクトの作り方が若干違うのがわかるかと思いますが、bs4のパーサに'lxml-xml'を指定してます。

僕は基本的に'lxml'パーサを使いますが、それのXML版です。

’lxml’のままでもパースできなくはないですが、キャメルバックになったタグが使えなくなったり、色々弊害が出てきたりするので、こちらをオススメします。

BeautifulSoupでXMLをパースする

基本的にHTMLのパースと要領は同じですが、復習を兼ねて、逆引きリファレンス的にまとめてみます。

上記コードの続きからです。

XMLのタグ名で検索し、最初に見つかる要素へアクセス

上記はどちらも同じ挙動で、「最初の<Self>タグ」にアクセスします。

Outは以下の通り。

XMLのタグ名で検索し、一致した全ての要素のリストを返す

上記はどちらも同じ挙動で、「全ての<Self>タグ」にアクセスし、リスト形式で返却します。

Outは以下の通り。

リスト形式ですので、返却されたオブジェクトを操作する場合はリストと同じようにインデックスアクセスして操作します。

例えば最後の<Self>タグにアクセスしたい場合は以下のように。

[-1]は最後の要素、[-2]なら最後から二番目の要素を返します。

子要素をリスト形式で返却

要素直下の各子要素をリスト形式で返却するメソッドもあります。

上記コードはsoup('Self')とした時と全く同じ結果が返ってきます。

XMLのテキストで検索する

テキストがわかっている時そのテキストを持つ要素にアクセスしたい場合は上記の通り。

ただ、そのテキスト本体にアクセスしてしまうので、基本的にこれだけでは何してるのか一切意味が分かりません(笑)

普通は、ここから更に、別の要素に展開させて行く使い方をします。

実践的にBeautifulSoupでXMLを加工してみる

大体使い方もわかったところで、少し実践的に加工してみます。

ProductCategoryIdと、ProductCategoryNameのテキストを一組2要素のタプルとして、階層順にリストとして保存。更に3つの各カテゴリ属性全てを同様に加工し別リストとして保存してみます。

複雑そうに見えますが、慣れればこの加工、2行で出来ます。

1行目は各カテゴリ分類をリスト形式で「Self」という変数に保存。

2行目のリスト内包表記は 「Self」に格納された各要素にアクセス。
各要素は「item」要素に格納されます。

「item('ProductCategoryId')」としてProductCategoryIdのタグ全てを取得していますが、そのままではタグごと取得してしまい、テキストを抜き出すことが出来ないため、更にリスト内包表記を使ってタグ内のtextにアクセスします。

ProductCategoryNameは必ずProductCategoryIdと一対の兄弟要素となっているため、Idタグにさえアクセスできれば「.next_sibling」で取得可能になります。

item_nodesに結果が保存されています。

BeautifulSoupによるXMLパース(解析) - 総括

HTMLのパースと感覚はほとんど一緒ですね。

'lxml-xml'を使うと、要素へのアトリビュートアクセスの時にキャメルバックのタグもそのままアクセスできますが、’lxml’だと小文字でしかアクセスできなかったりと、細かい違いはところどころに存在します。

今回はパース(解析)の方法を紹介しましたが、実はBeautifulSoupはXMLの作成もできたりします。

こちらの記事ではYahooAPIを題材にBeautifulSoupでゼロから作成したXMLドキュメントでリクエストを行う方法を紹介していますので、ぜひ参考にしてみてください。

¥2,700 (2019/09/19 00:25:02時点 Amazon調べ-詳細)