メインコンテンツへスキップ

BeautifulSoupを使ったXMLの解析

··2511 文字·6 分
目次

はじめに
#

BeautifulSoupを使ってXMLを解析(parse)します。

環境
#

2020-11-07: 以下の環境で検証しました。

  • Python 3.7.4
  • beautifulsoup4 4.8.0
  • lxml 4.4.1

2025-10-13追記: 以下の環境でも検証しました。

  • Python 3.13.7
  • beautifulsoup4 4.14.2
  • lxml 6.0.2

インストール
#

ターミナルで以下のコマンドを実行し、beautifulsoup4lxmlをインストールします。

pip install beautifulsoup4 lxml

uv の場合は以下になります。

uv add beautifulsoup4 lxml

XMLの構文
#

この記事では、XMLの構造について以下の名称を用います。

<要素名 属性="値">内容</要素名>

扱うXMLファイル
#

書籍データを模擬したXMLファイルを扱います。 以下のXMLにdoc.xmlと名前を付けて、作業ディレクトリに置いていることを前提とします。 また、文字エンコーディングはUTF-8として下さい。

<data>
  <book id="001">
    <title language="English">Alice in Wonderland</title>
    <author autonym="Charles Lutwidge Dodgson">Lewis Carroll</author>
    <genre>小説</genre>
  </book>
  <book id="002">
    <title language="Japanese">羅生門</title>
    <author autonym="芥川龍之介">芥川龍之介</author>
    <genre>小説</genre>
  </book> 
  <book id="003">
    <title language="Japanese">柿の種</title>
    <author autonym="寺田寅彦">寺田寅彦</author>
    <genre>随筆</genre>
  </book>
</data>

“autonym"は「本名」の意味です。 また、この記事では扱いませんが、requestやurllibなどのライブラリを使うと、インターネット上のXMLファイルを自動で収集できます。

XMLファイルのパース
#

読み込んだXMLファイルオブジェクトをBeautifulSoupでパースします。 BeautifulSoupで使用できるパーサを次表に示します。 今回はlxmlパーサを使用します。

パーサ 説明
html.parser 標準ライブラリのパーサ
lxml lxmlライブラリのHTMLパーサ。処理が高速
lxml-xml または xml lxmlライブラリのXMLパーサ。処理が高速
html5lib HTML5に対応

以下のようにBeautifulSoupをインポートして、XMLファイルとパーサを引数に指定します。 BeautifulSoupオブジェクトのsoupptint文で出力すると、XMLが表示されます。

>>> from bs4 import BeautifulSoup
>>> with open("doc.xml", encoding="utf-8") as f:
...     soup = BeautifulSoup(f, features="xml")  # featuresでパーサを指定
>>> print(soup)
<?xml version="1.0" encoding="utf-8"?>
<data>
<book id="001">
<title language="English">Alice in Wonderland</title>
<author autonym="Charles Lutwidge Dodgson">Lewis Carroll</author>
<genre>小説</genre>
</book>
<book id="002">
<title language="Japanese">羅生門</title>
<author autonym="芥川龍之介">芥川龍之介</author>
<genre>小説</genre>
</book>
<book id="003">
<title language="Japanese">柿の種</title>
<author autonym="寺田寅彦">寺田寅彦</author>
<genre>随筆</genre>
</book>
</data>

XMLが文字化けする場合はopen時のencodingを見直して下さい。 また、prettify()メソッドを使うとインデントで整形されたXMLが表示されます。

>>> print(soup.prettify())
<?xml version="1.0" encoding="utf-8"?>
<data>
 <book id="001">
  <title language="English">
   Alice in Wonderland
  </title>
  <author autonym="Charles Lutwidge Dodgson">
   Lewis Carroll
  </author>
  <genre>
   小説
  </genre>
 </book>
 <book id="002">
  <title language="Japanese">
   羅生門
  </title>
  <author autonym="芥川龍之介">
   芥川龍之介
  </author>
  <genre>
   小説
  </genre>
 </book>
 <book id="003">
  <title language="Japanese">
   柿の種
  </title>
  <author autonym="寺田寅彦">
   寺田寅彦
  </author>
  <genre>
   随筆
  </genre>
 </book>
</data>

パースしたXMLの探索
#

要素の検索
#

以下のメソッドをXML内の要素の探索に利用できます。

メソッド 説明
find() 要素名または属性で検索し、該当する最初の要素を返す
find_all() 要素名または属性で検索し、該当する全ての要素を返す

使用例は次の通り。

>>> soup.find("book")  # 最初の"book"要素
<book id="001">
<title language="English">Alice in Wonderland</title>
<author autonym="Charles Lutwidge Dodgson">Lewis Carroll</author>
<genre>小説</genre>
</book>
>>> soup.book  # ".要素"でも同じ結果になる
<book id="001">
<title language="English">Alice in Wonderland</title>
<author autonym="Charles Lutwidge Dodgson">Lewis Carroll</author>
<genre>小説</genre>
</book>
>>> soup.find(language="Japanese")  # language属性がJapaneseである最初の要素
<title language="Japanese">羅生門</title>
>>> soup.find_all("author")  # 全てのauthor要素
[<author autonym="Charles Lutwidge Dodgson">Lewis Carroll</author>,
 <author autonym="芥川龍之介">芥川龍之介</author>,
 <author autonym="寺田寅彦">寺田寅彦</author>]
>>> soup.find_all(language="Japanese")  # language属性がJapaneseである全ての要素
[<title language="Japanese">羅生門</title>,
 <title language="Japanese">柿の種</title>]

属性と値の取得
#

属性から値を取得する場合は[ ]で属性を指定します。 全ての属性と値を取得する場合はattrsメンバを使います。

>>> title001 = soup.book.title
>>> print(title001)
<title language="English">Alice in Wonderland</title>
>>> title001["language"]  # 属性を指定
'English'
>>> title001.attrs  # 属性と値を辞書型で表示
{'language': 'English'}

内容の取得
#

内容を持つ直上の要素まで移動し、stringメンバを使います。

>>> title001 = soup.book.title
>>> print(title001)
<title language="English">Alice in Wonderland</title>
>>> title001.string  # 内容を取得
"Alice in Wonderland"

要素間の移動
#

メンバ 説明
next_sibling 同じ階層の次の要素に移動
previous_sibling 同じ階層の前の要素に移動
parent 上の階層の要素に移動
>>> book001 = soup.book
>>> print(book001)
<book id="001">
<title language="English">Alice in Wonderland</title>
<author autonym="Charles Lutwidge Dodgson">Lewis Carroll</author>
<genre>小説</genre>
</book>
>>> author001 = book001.author
>>> print(author001)
<author autonym="Charles Lutwidge Dodgson">Lewis Carroll</author>
>>> author001.next_sibling  # 改行(\n)も要素に含まれる
'\n'
>>> author001.next_sibling.next_sibling  # 次の要素
<genre>小説</genre>
>>> author001.previous_sibling.previous_sibling  # 前の要素
<title language="English">Alice in Wonderland</title>
>>> author001.parent  # 上の要素
<book id="001">
<title language="English">Alice in Wonderland</title>
<author autonym="Charles Lutwidge Dodgson">Lewis Carroll</author>
<genre>小説</genre>
</book>

参考リンク
#

Beautiful Soup Documentation — Beautiful Soup documentation

Helve
著者
Helve
関西在住、電機メーカ勤務のエンジニア。X(旧Twitter)で新着記事を配信中です

関連記事

NumPyで使える統計の関数
·673 文字·2 分
NumPyで利用できる統計の関数について。
NumPyで使える数学の関数
·1029 文字·3 分
NumPyで利用できる数学の関数について。
NumPy配列の演算
·1220 文字·3 分
NumPy配列の四則演算と線形代数学の演算について。
NumPy配列の操作
·1330 文字·3 分
NumPy配列のコピーや次元の結合、結合・分割、ソートについて。
NumPy配列の確認
·974 文字·2 分
作成したNumPy配列の要素などを確認する。
NumPyによる配列の作成
·2334 文字·5 分
NumPyを使って基本的な配列や線形代数学でよく使われる配列を生成する。