Hello _ world

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

出自廖雪峰python3教程课后练习题

 

首先写一下两个让我掉坑里的知识点:

一、SAX解析XML

在Python中使用SAX解析XML非常简洁,SAX是流模式,边读边解析,占用内存小,解析快,缺点是我们需要自己处理事件。

常我们关心的事件是start_elementend_elementchar_data,准备好这3个函数,然后就可以解析xml了。

举个例子,当SAX解析器读到一个节点时:

<a href="/">python</a>

会产生3个事件:

  1. start_element事件,在读取<a href="/">时;

  2. char_data事件,在读取python时;

  3. end_element事件,在读取</a>时。

再结合本练习题说明:

    SAX解析器读到一个节点:

<yweather:condition code="32" date="Sat, 10 Mar 2018 08:00 AM CST" temp="37" text="Sunny"/>

因为没有单独的关闭标签,所以会产生2个事件:

         1、start_element事件,name是yweather:condition,attrs是dict类型,值为{'code': '32', 'date': 'Sat, 10 Mar 2018 08:00 AM CST', 'temp': '37', 'text': 'Sunny'};

         2、end_element事件,name是yweather:condition。

二、结果的存放

练习题的最后结果要是这种格式:

{
    'city': 'Beijing',
    'forecast': [
        {
            'date': '2017-11-17',
            'high': 43,
            'low' : 26
        },
        {
            'date': '2017-11-18',
            'high': 41,
            'low' : 20
        },
        {
            'date': '2017-11-19',
            'high': 43,
            'low' : 19
        }
    ]
}

分析可得,结果是dict类型,key('city')对应的value是'Beijing',key('forecast)对应的value是一个list,并且list中存放的是一个个dict!!!

由于先前对dict和list认识不清,是这样错误的存放数据的:

Weather['city'] = attrs['city']    #读取城市,没问题,接下来读取每天天气情况就出错了

day = 0   #第一天的天气情况

Weather['forecast'][day]['date'] = attrs['date']

Weather['forecast'][day]['high'] = attrs['high']

Weather['forecast'][day]['low'] = attrs['low']

day = day + 1   #接下去一天

任何一门语言,入门容易,想熟练掌握,无他,只能唯手熟尔!

 

最后贴出自己写的练习题代码:

# -*- coding: utf-8 -*-

from xml.parsers.expat import ParserCreate
from urllib import request

class DefaultSaxHandler(object):
    def __init__(self):
        self.data = {}   #存放天气预报结果,是dict类型

    def start_element(self, name, attrs):
        if name == 'yweather:location':         #读取城市
            self.data['city'] = attrs['city']    #键为‘city’, 值为city
            self.data['forecast'] = []           #键为‘forecast’,值为list类型,其中以dict类型存放每天的时间、最高温度、最低温度

        if name == 'yweather:forecast':
            dateDict = {}             #每天的天气情况
            dateDict['date'] = attrs['date']   #日期
            dateDict['high'] = attrs['high']   #最高温度
            dateDict['low'] = attrs['low']     #最低温度
            self.data['forecast'].append(dateDict)   #将该日天气情况添加到list中

def parseXml(xml_str):
    print(xml_str)
    handler = DefaultSaxHandler()
    parser = ParserCreate()
    parser.StartElementHandler = handler.start_element
    parser.Parse(xml_str)
    #print(handler.data)   #结果
    return handler.data

# 测试:
URL = 'https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20%3D%202151330&format=xml'
with request.urlopen(URL, timeout=4) as f:
    data = f.read()
result = parseXml(data.decode('utf-8'))
assert result['city'] == 'Beijing'

 

posted on 2018-03-10 13:58  Hello _ world  阅读(310)  评论(0编辑  收藏  举报