zoukankan      html  css  js  c++  java
  • 7、利用SAX编写程序解析Yahoo的XML格式的天气预报,获取天气预报

    出自廖雪峰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'
  • 相关阅读:
    equals与”==”的区别
    数学--数论--积性函数(初步)
    数学--数论-多重集排列组合与母函数
    数学--数论--POJ 1061青蛙的约会 (扩展欧几里得算法)
    数学--数论--POJ281(线性同余方程)
    数学--数论--HDU1222 狼和兔子(最大公约数)
    数学--数论--HDU1576 A / B(逆元)
    VScode像Codeblocks一样,不启动调试和Debug直接运行
    数学--数论--鸽巢原理
    图论--拓扑排序--模板
  • 原文地址:https://www.cnblogs.com/zwb8848happy/p/8538985.html
Copyright © 2011-2022 走看看