Python 3で、iTunesのXMLをパースする その1


このエントリーをはてなブックマークに追加

AppleiTunesで曲を管理していると、"iTunes Music Library.xml"というXMLファイルが自動生成されます。このファイルを分析することで、「もっとも曲数が多いアーティスト」「リリース年別の曲数の遷移」などさまざまな情報を抽出できます。

今回はPython 3を使って、チュートリアル風にXMLからの情報抽出の仕方を説明していきます。

XMLについて知る

Windows 7の場合、iTunesXMLの場所は "C:\Users(ユーザ名)\Music\iTunes\iTunes Music Library.xml"だと思います。自分の場合、iTunesに約35,000曲入っていて、XMLの容量は約83MBです。

XMLの中身を見ると以下のようになっています。(手直ししています)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Major Version</key><integer>1</integer>
        <key>Minor Version</key><integer>1</integer>
            ...
        <key>Tracks</key>
        <dict>
                <key>40086</key>
                <dict>
                        <key>Track ID</key><integer>40086</integer>
                        <key>Name</key><string>I Saw Her Standing There</string>
                        <key>Artist</key><string>The Beatles</string>
                        <key>Album Artist</key><string>The Beatles</string>
                        <key>Composer</key><string>John Lennon/Paul McCartney</string>
                        <key>Album</key><string>Please Please Me</string>
                                 ...
                </dict>
        </dict>
        ...

これを見ると、

<plist>
  <dict>
     <key>Tracks<key>
     <dict>
        <key>(数字)</key>
        <dict>
           1曲めに関する情報
        </dict>
     </dict>
     <dict>
        <key>(数字)</key>
        <dict>
           2曲めに関する情報
        </dict>
     </dict>
     ..(以下繰り返し)..
  </dict>
</plist>

となっていそうなことが分かります。

ライブラリを使ってXMLをパースする

XMLのパースについては XML - Dive Into Python 3 日本語版 の説明が素晴らしいです。このページでは以下の2つのパーサーが紹介されています。

  • ElementTreeライブラリ (Python 3の標準ライブラリ)
  • lxmlライブラリ (3rdpartyのライブラリ)

ElementTreeライブラリは遅すぎる

まずはElementTreeライブラリを試してみます。以下のコードを書き、引数にXMLのパスを入れて実行します。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
import xml.etree.ElementTree as etree

# XMLを読み込み
xml_path = sys.argv[1]
tree = etree.parse(xml_path)

単にXMLを読み込むだけで、44秒もかかってしまいました。これでは遅すぎです。

lxmlライブラリは高速

次にlxmlライブラリを試してみます。pip install lxmlなどでライブラリを使えるようにしたあと、以下のコード(一行変えただけ)をさきほどと同様に実行します。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
from lxml import etree

# XMLを読み込み
xml_path = sys.argv[1]
tree = etree.parse(xml_path)

今度は3.4秒ほどで実行できました。10倍以上早く読み込むことができました。lxmlは内部でCのライブラリを使っているため高速なのだと思われます。

Python 3で、iTunesのXMLをパースする その2 - minus9d's diaryに続きます。