XMLファイルをPythonで解析する

6313 ワード

翻訳:https://developer.yahoo.com/python/python-xml.html
Pythonを使用してXMLファイルを解析する
多くのYDN APIsはJSON形式のデータ出力を提供しており、JSONはほとんどの場合に有用なデータ構造である.しかしAPIはJSONデータ出力を提供していないため,PythonのXMLモジュールを用いてデータを解析することができる.
Using minidom
Using ElementTree
minidomの使用
Pythonにはa full DOM implementationとxml.dom.minidomの2つのモジュールがあり、後者はYahooを処理するのに適しています.のAPI
以下にxml.dom.minidomでYahooAPIを解析する例を示す
import urllib
from xml.dom import minidom

WEATHER_URL = 'http://xml.weather.yahoo.com/forecastrss?p=%s'
WEATHER_NS = 'http://xml.weather.yahoo.com/ns/rss/1.0'

def weather_for_zip(zip_code):
    url = WEATHER_URL % zip_code
    dom = minidom.parse(urllib.urlopen(url))
minidom.parse()はクラスファイルオブジェクトを処理します.このオブジェクトはurllib.urlopen()を使用して返します.
forecasts = []
    for node in dom.getElementsByTagNameNS(WEATHER_NS, 'forecast'):
    forecasts.append({
        'date': node.getAttribute('date'),
        'low': node.getAttribute('low'),
        'high': node.getAttribute('high'),
        'condition': node.getAttribute('text')
    })
getElementsByTagNameNS()は名前空間感知関数であり、2つの関数が必要であり、最初のパラメータは名前空間のURLであり、2番目のパラメータはラベルの名前である.getElementsByTagName('yweather:forecast')を使用して置き換えることができますが、前者はプログラムをより丈夫にすることができます.
ycondition = dom.getElementsByTagNameNS(WEATHER_NS, 'condition')[0]
    return {
        'current_condition': ycondition.getAttribute('text'),
        'current_temp': ycondition.getAttribute('temp'),
        'forecasts': forecasts,
        'title': dom.getElementsByTagName('title')[0].firstChild.data
    }
最後の行のfirstChild.dataは、ドキュメントの最初の要素を取得する役割を果たす.
完全なコードは次のとおりです.
import urllib
from xml.dom import minidom

WEATHER_URL = 'http://xml.weather.yahoo.com/forecastrss?p=%s'
WEATHER_NS = 'http://xml.weather.yahoo.com/ns/rss/1.0'

def weather_for_zip(zip_code):
    url = WEATHER_URL % zip_code
    dom = minidom.parse(urllib.urlopen(url))
    forecasts = []
    for node in dom.getElementsByTagNameNS(WEATHER_NS, 'forecast'):
        forecasts.append({
            'date': node.getAttribute('date'),
            'low': node.getAttribute('low'),
            'high': node.getAttribute('high'),
            'condition': node.getAttribute('text')
        })
    ycondition = dom.getElementsByTagNameNS(WEATHER_NS, 'condition')[0]
    return {
        'current_condition': ycondition.getAttribute('text'),
        'current_temp': ycondition.getAttribute('temp'),
        'forecasts': forecasts,
        'title': dom.getElementsByTagName('title')[0].firstChild.data
    }

次に実験を行いますzip code:66044
>>> from pprint import pprint
>>> pprint(weather_for_zip(66044))
{'current_condition': u'Fair',
 'current_temp': u'85',
 'forecasts': [{'condition': u'Mostly Sunny',
                'date': u'20 Jul 2006',
                'high': u'103',
                'low': u'75'},
               {'condition': u'Scattered Thunderstorms',
                'date': u'21 Jul 2006',
                'high': u'82',
                'low': u'61'}],
 'title': u'Yahoo! Weather - Lawrence, KS'}

ElementTreeを使用して、ElementTree APIを使用して、上記の例を実装します.
import urllib
from elementtree.ElementTree import parse

WEATHER_URL = 'http://xml.weather.yahoo.com/forecastrss?p=%s'
WEATHER_NS = 'http://xml.weather.yahoo.com/ns/rss/1.0'

def weather_for_zip(zip_code):
	url = WEATHER_URL % zip_code
	rss = parse(urllib.urlopen(url)).getroot()
ElementTreeのparse()メソッドは、クラスファイルオブジェクトを処理し、XMLファイル全体に対応するElementTreeオブジェクトを返します.getroot()この方法は、この例では要素である要素ツリーのルートを取得する.
forecasts = []
        for element in rss.findall('channel/item/{%s}forecast' % WEATHER_NS):
            forecasts.append({
                'date': element.get('date'),
                'low': element.get('low'),
                'high': element.get('high'),
                'condition': element.get('text')
            })
ここではモード検索で検索<yweather:forecast>元素、この元素はのサブ元素であり、のサブ元素である.これらの要素はget()メソッドを使用して属性を取得できます.
次に、<yweather:condition>要素を探します.
    ycondition = rss.find('channel/item/{%s}condition' % WEATHER_NS)
    return {
        'current_condition': ycondition.get('text'),
        'current_temp': ycondition.get('temp'),
        'forecasts': forecasts,
        'title': rss.findtext('channel/title')
    }

次は完全なコードです.
import urllib
from elementtree.ElementTree import parse

WEATHER_URL = 'http://xml.weather.yahoo.com/forecastrss?p=%s'
WEATHER_NS = 'http://xml.weather.yahoo.com/ns/rss/1.0'

def weather_for_zip(zip_code):
    url = WEATHER_URL % zip_code
    rss = parse(urllib.urlopen(url)).getroot()
    forecasts = []
    for element in rss.findall('channel/item/{%s}forecast' % WEATHER_NS):
        forecasts.append({
            'date': element.get('date'),
            'low': element.get('low'),
            'high': element.get('high'),
            'condition': element.get('text')
        })
    ycondition = rss.find('channel/item/{%s}condition' % WEATHER_NS)
    return {
        'current_condition': ycondition.get('text'),
        'current_temp': ycondition.get('temp'),
        'forecasts': forecasts,
        'title': rss.findtext('channel/title')
    }