読者です 読者をやめる 読者になる 読者になる

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

python

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

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

XPathを使ってXMLを探索

XMLから所望のデータを取り出すには、XPathと呼ばれる、XMLのツリーのうち特定の条件にあった部分を取り出すための言語を使うのがよいでしょう。

今回のXMLの場合、ルートノードからdictが3つ続いた後に曲情報が入っているので、以下のように書けばよいようです。

    # XMLを読み込み
    tree = etree.parse(xml_path)
    root = tree.getroot()

    songs = root.findall('dict/dict/dict')

この下にはとが交互に並んでいるので、これらを順に読み込んでdict型の変数song_infoに放り込みます。できあがったらリスト(song_info_list)に追加します。

    # 曲ごとの情報を取得
    song_info_list = []
    for song in songs:
        song_info = {}
        key = ""
        for element in song:
            if element.tag == "key":
                key = element.text
            else:
                song_info[ key ] = element.text
        song_info_list.append( song_info )

song_infoの例は以下です。

{'Album': 'Please Please Me', 'Track Number': '1', 'Album Artist': 'The Beatles', 'Track Type': 'File', 'Total Time': '175800', 'Year': '1963', ... }

あとはご自由に

song_info_listができてしまいさえすれば、あとは好きな情報を取り出すだけです。

例えば、曲数が多い順にアーティストを並べて上位top件を表示するには以下のように書けます。collections.Counterクラスを使うのがこの用途にはぴったりです。

import collections

def artists_with_many_songs(song_info_list, top = 10):

    counter = collections.Counter()
    for song_info in song_info_list:
        # たまに"Artist"の項目が空のことがある
        if "Artist" not in song_info:
            continue
        # podcastは除外
        elif "Genre" in song_info and song_info["Genre"] == "Podcast":
            continue

        counter[ song_info["Artist"] ] += 1

同様に、「もっとも再生したアーティスト」「もっとも再生したアルバム」「リリース年の遷移」なども簡単に抽出することができます。

ソースコード

python_exercise/itunes_xml_parser at master · minus9d/python_exerciseにUPしました。

参考