用Python解析XML文件

本文翻译自:https://developer.yahoo.com/python/python-xml.html

使用Python解析XML文件

许多YDN APIs提供了JSON格式的数据输出,JSON对于对于大部分情况来说都是有用的数据结构。但是API没有提供JSON数据输出,那么可以使用Python的XML模块解析数据。

使用 minidom

Python有a full DOM implementationxml.dom.minidom两个模块可供用来解析XML,后者更适合处理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()是一个名字空间感知函数,它需要两个函数,第一个参数是名字空间的URL,第二个参数是标签的名字。我们可以使用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作用是取得文档(document)第一个元素。

下面是完整代码:

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()方法处理一个类文件对象并返回一个ElementTree对象,这个对象对应整个XML文件。 getroot()这个方法取得元素树的根,在这个例子中就是<rss>元素。

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>元素,这个元素是<item>的子元素,<item>又是<channel>的子元素。这些元素可以使用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')
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值