17.01.2012 - Google Weather Api

Google's weather API + Python + Django

Google offers weather data via XML feed. The can be accessed with the following URL:

http://www.google.com/ig/api?weather=[LOCATION]&hl=[LANGUAGE]

LOCATION: The LOCATION parameter defines the weather station. This can be a country together with a postal code (POSTAL CODE-COUNTRY) or the name of a city. The former method provides a more accurate result because there exit two or more cities with the same name.

LANGUAGE: The LANGUAGE parameter determinates the language of the provided XML feed. Valid values can be found here: http://code.google.com/intl/de-DE/apis/language/translate/v1/reference.html#LangNameArray

Let's get the actual weather and a weather forecast for the next days for Caleta de Fuste on Fuerteventura: The LOCATION and LANGUAGE parameters will be: '35610-Fuerteventura' and 'en'. Open the following link to get an XML feed with the actual weather information for Caleta de Fuste: http://www.google.com/ig/api?weather=35610-Fuerteventura&hl=en.

Here is an example for converting the feed into python dictionaries and lists:

#!/usr/bin/env python # -*- coding: UTF-8 -*- # vim: ai ts=4 sts=4 et sw=4 import xml.dom.minidom import urllib import urllib2 def weathertodict(xmlstring): doc = xml.dom.minidom.parseString(xmlstring) return elementtodict(doc.documentElement) def elementtodict(parent): # get first child child = parent.firstChild if (not child): return None elif (child.hasAttribute('data')): # convert tags and data attributes to dictionary v = {} while child.nextSibling: v.update({child.tagName : child.getAttribute('data')}) child = child.nextSibling return v d={} while child is not None: if (child.nodeType == xml.dom.minidom.Node.ELEMENT_NODE): # create or extend entry with tag name try: d[child.tagName] except KeyError: d[child.tagName]=[] # append node values, recursive call d[child.tagName].append(elementtodict(child)) # select next sibling child = child.nextSibling return d def main(): request = 'http://www.google.com/ig/api?weather=%s&hl=%s' % ('35610-Fuerteventura', 'de') xml = unicode(urllib2.urlopen(urllib2.Request(request)).read(), 'ISO-8859-1').encode('utf-8') weather_dict = weathertodict(xml) weather = weather_dict.get('weather')[0] info = weather.get('forecast_information')[0] current = weather.get('current_conditions')[0] forecast = weather.get('forecast_conditions') print '#'*20 print info print '#'*20 print current print '#'*20 print forecast if __name__ == "__main__": main()

Django template tag

The aforementioned methods can be used in a django inclusion tag to show actual weather information for a specific location in a Django template:

#!/usr/bin/env python # -*- coding: UTF-8 -*- # vim: ai ts=4 sts=4 et sw=4 import urllib import urllib2 from django import template from google_weather.utils import weathertodict register = template.Library() @register.inclusion_tag('google_weather/weather_widget.html') def google_weather(location, language): request = 'http://www.google.com/ig/api?weather=%s&hl=%s' % (location, language) xml = unicode(urllib2.urlopen(urllib2.Request(request)).read(), 'ISO-8859-1').encode('utf-8') weather_dict = weathertodict(xml).get('weather')[0] return { 'weather_dict' : weather_dict, }

An example for weather_widget.html could look like this:

<div class="forecast"> <!-- forecast information --> <div class="forecast-information"> <span class="city">{{ weather_dict.forecast_information.0.city }}</span> </div> <!-- current conditions --> <div class="current-conditions"> <span class="icon"><img src="http://www.google.com/{{ weather_dict.current_conditions.0.icon }}" /></span> <span class="temp">{{ weather_dict.current_conditions.0.temp_c }} °C</span> <span class="condition">{{ weather_dict.current_conditions.0.condition }}</span> <span class="humidity">{{ weather_dict.current_conditions.0.humidity }}</span> </div> <!-- forecasts --> <div class="forecasts"> {% for day in weather_dict.forecast_conditions %} <div class="forecast-day"> <span class="icon"><img src="http://www.google.com/{{ day.icon }}" /></span> <span class="day">{{ day.day_of_week }}</span> <span class="high-low">{{ day.high }}°C / {{ day.low }}°C</span> </div> {% endfor %} </div> </div>

loader

Impressum

Marco Carolla
Detmolder Str. 47
33604 Bielefeld

i n f o [ a t ] n o t i o n b o x . d e