Question

I feel like I'm stuck and would really appreciate all forms of help and guidance.

I have an XML downloaded from yr.no (norweigan weather report). It contains several elements with weather reports from different times of the day. It has 3 reports per day but I just want to use one of them and I want to print out the weather for the next 7 days. I have so far managed to print out the weather for all days, or just one. I have however not figured how to "sort out" the ones from the wrong time period.

This is my latest attempt to just get 1 out of 3 reports. Every report is in three elements, what makes them unique is their attributes. I will below my code show a couple of lines from the xml. If your want to download the whole xml to see the structure, I will put a link to that at the bottom.

My latest attempt:

with open('Stockholm.xml', 'rt') as wreport:
    tree = ET.parse(wreport)

for temp in tree.getiterator("temperature"):
    counter = 2
    if counter == 0 or counter == 1:
        counter += 1
    elif counter == 2:
        counter -= 2
        print "In Stockholm it will today be %s celcius" % (temp.get("value"))

The XML, from which I would like to reach the element "temperature" from the first seven elements named "time" that got period="2":

<forecast>
 <tabular>
   <time from="2014-01-03T12:00:00" to="2014-01-03T18:00:00" period="2">
    <!--
    Valid from 2014-01-03T12:00:00 to 2014-01-03T18:00:00 
    -->
    <symbol number="4" name="Skya" var="04"/>
    <precipitation value="0.1" minvalue="0.1" maxvalue="0.2"/>
    <!--  Valid at 2014-01-03T12:00:00  -->
    <windDirection deg="163.3" code="SSE" name="Sør-søraust"/>
    <windSpeed mps="4.6" name="Lett bris"/>
    <temperature unit="celsius" value="4"/>
    <pressure unit="hPa" value="1007.0"/>
   </time>
<time from="2014-01-03T18:00:00" to="2014-01-04T00:00:00" period="3">...</time>
<time from="2014-01-04T00:00:00" to="2014-01-04T06:00:00" period="0">...</time>
<time from="2014-01-04T06:00:00" to="2014-01-04T12:00:00" period="1">...</time>

In all of the you can get the same elements that I showed in the first time. Download link here: http://www.yr.no/stad/Sverige/Stockholm/Stockholm/varsel.xml

Was it helpful?

Solution

You should iterate first over the 'time' elements to filter them according your needs. After that you can iterate over the 'temperature' sub-elements. Something like this:

import lxml.etree as etree

with open('Stockholm.xml', 'rt') as wreport:
    xml = etree.parse(wreport)
    for record in xml.iter('time'):
        if record.attrib['period'] == '2':
            for temp in record.iter('temperature'):
                print 'In Stockholm it will today be %s celcius from %s to %s\n' %
                        (temp.attrib['value'], 
                        record.attrib['from'], 
                        record.attrib['to'])

Alternatively, you can use XPath like filtering:

import lxml.etree as etree

with open('Stockholm.xml', 'rt') as wreport:
    xml = etree.parse(wreport)
        for temp in xml.findall('.//time[@period="2"]/temperature'):
            print 'In Stockholm it will today be %s celcius\n' % 
                            temp.attrib['value']

OTHER TIPS

There is module python-yr available these days and it's really easy to use. It delivers JSON data from yr.no

Check this out: https://github.com/wckd/python-yr

Example:

#!/usr/bin/env python3

from yr.libyr import Yr
import dateutil.parser


weather = Yr( location_name='Czech_Republic/Central_Bohemia/Kralupy_nad_Vltavou', forecast_link='forecast', )

day_before=""  # days separator print line flag

for forecast in weather.forecast():

    day = dateutil.parser.parse(forecast['@from']).strftime("%A")

    if day_before != day:
        print()
        day_before = day


    time_from = dateutil.parser.parse(forecast['@from']).strftime("%d.%m.%Y %H:%M")

    time_to = dateutil.parser.parse(forecast['@to']).strftime("%H:%M%p")
    sky = forecast['symbol']['@name']
    wind = forecast['windSpeed']['@name']
    wind_speed = forecast['windSpeed']['@mps']
    precipitation = forecast['precipitation']['@value']
    temperature = forecast['temperature']['@value']
    print("{0:<7} {1}-{2}  {7:>2}°C  {3:<18}, wind {5:<4} m/s, prec.: {6:<3} mm ".format(
                    day,
                    time_from,
                    time_to,
                    sky,
                    wind,
                    wind_speed,
                    precipitation,
                    temperature))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top