Yahoo! Weather Feeds With Python


UPDATE: Chris Lasher updated my script. It now utilizes optparse and docstrings. Some of the options have been changed, too, and I have licensed the code under a by-nc-sa CC license. I have updated this post to reflect these changes. Thanks, Chris!

I believe that everyone likes to know what the weather is like outside. In the good ol’ days, people used to stick a hand out of the window and know everything they needed to know about the weather; now we have myriad options to check the weather.

A few years ago, I was running Konfabulator on Windows. The best widget for this application was the weather widget. I had a large weather widget that showed the current weather in the town in which I was currently residing, and some smaller weather widgets allowed me to keep tabs on the weather elsewhere.

When I got my Powerbook in 2004, I continued to use Konfabulator. With Tiger came Dashboard in 2005; I promptly started using the weather widgets provided by Dashboard. However, I realized that the requirement that I switch contexts to Dashboard just to quickly check small tidbits of information greatly distracted me from my workflow. Even the ability to display widgets directly on the desktop was no help; the pretty images take up too much screen real estate.

As I have written about in the past, I utilize Geek Tool on my desktop. One of the scripts I run scrapes the Weather Underground XML feed for Blacksburg, VA and displays the current conditions. This works fine, but it isn’t very extensible. Weather Underground does not appear to have a feed API, so each city’s XML feed must be found manually and utilized in the script. Last night I decided that this was unacceptable.

Yahoo offers a great RSS-based API for its weather services. Python has a built-in XML parser. It doesn’t take a rocket surgeon to put those two together. With a little help from Yahoo’s Developer Network, I was able to come up with a more robust script with which the weather can be displayed.

I learned a few things regarding Python while writing this script. The getopt() method is a very useful command-line options and arguments parser. It’s very simple to define options for your script using this method.

import getopt
import sys

opts, args = getopt(sys.argv[1:], "cflv")

Now the options that were passed on the command line and that are part of cflv are in the opts array; command line arguments are listed in args.

UPDATE: My script now uses optparse instead of getopt.

minidom is a simple but complete DOM implementation. Using the getElementsByTagName and the getAttribute methods makes for easy and stress-free XML parsing.

from xml.dom.minidom import parse

dom = parse("file.xml")

attrs = []

for node in dom.getElementsByTagName('tag'):
    attrs.append(node.getAttribute('text'))

attrs contains the text attribute of each tag node in the XML file file.xml.

I am currently looking into building this script on top of a Twitter model. Keep checking in for more information.

In order to run the script, pass it a zip code to find the weather.

$ weather.py 24060

Running the script without any arguments will show the usage and the available options.

  • -c Suppress the current weather output. Use this if you only want the forecast data.
  • -f DAYS Show the forecast for the next DAYS days.
  • -l Show the city and region name of the forecast that was retrieved. Use this to verify the zip code that you are using is in fact your area.
  • -v Print headers above all output.

Here is some example output from the script:

Default options:

$ weather.py 24060
55F | Drizzle

Forecast and location options:

$ weather.py -lf2 24060
Blacksburg, VA

55F | Drizzle

22 Apr 2008
  Low: 50F
  High: 60F
  Condition: Few Showers

23 Apr 2008
  Low: 49F
  High: 71F
  Condition: AM Clouds/PM Sun

39 comments

  1. 2

    Attempt #3 to post a comment.

    My response.

  2. 3

    Thanks for your response, Chris. I’ve updated the script to include your additions, and I’ve licensed the script under a BF-NC-SA CC license.

  3. 4

    Thanks for the blog post on this, it was very informative.

    And I just graduated (again) from Virginia Tech, so go Hokies!

  4. 5

    [...] (i = 8; i %3C 11; i++) if ($i != “-”) printf $i ” “; else break; printf “n”}’ UPDATE: I now use a Python script that uses the Yahoo! Weather API to get weather data. This bash script scrapes the Weather Underground feed for Blacksburg and [...]

  5. 6

    A great script Thomas, To make it work for us that does not live in US I did some minor changes:

    1. remove the part where it checks if the zipcode is digits:

      #if len(zipcode) != 5 or not zipcode.isdigit():
      
      cli_parser.error("ZIP code must be 5 digits")
    2. add a &u=c at the end of the rss url to make it metric:

      WEATHER_URL = 'http://xml.weather.yahoo.com/
      forecastrss?p=%s&u=c'
  6. 7

    @Jon:

    I updated the script to allow for Yahoo! international location codes. You can now pass the script the option -m in order to return weather in metric units.

    Thanks for letting me know that this didn’t work for you. I tested it with multiple international locations, but please let me know if there are any other problems.

    The download link is now a little more prominent at the top of this post, or you can get it here: Python Yahoo Weather

  7. 8

    @Thomas, that was fast. Thanks. It seems to work for the locations I use it for now.

    If I could only get it to use a nice ° instead of the C and everything would be perfect.

  8. 9

    @Jon:

    The problem with using the degree symbol (° U+00B0) is that I have no idea how to print that Unicode symbol in a Python string. I agree, though, it would make it look nice.

  9. 10

    @Thomas: I will try to see what I can figure out about unicode and python, but as this was my first time ever looking at a python-script and first time since I started working that I looked at any code at all I don’t think that I will figure something out too soon.

    It was fun getting back to reading code though. Thanks so far.

  10. 11

    [...] (i = 8; i %3C 11; i++) if ($i != “-”) printf $i ” “; else break; printf “n”}’ UPDATE: I now use a Python script that uses the Yahoo! Weather API to get weather [...]

  11. 12

    Total Newb- please upload script and easy instructions somewhere.

    I’m in desperate need of a great weather script like this.

    again, Please!

  12. 13

    @Marnu — Click here to download the script. There is a download link near the top of the page, where you can download a zip or tar of the project. Decompress the download, then run the script with python weather.py 24060.

    Let me know if I can be of any more help.

  13. 14

    Thank you so much! This has been driving me crazy trying to use Lynx.

  14. 15

    @David — Glad that I could help. Let me know if you have any questions!

  15. 16

    @thomas — python weather.py 90024 works great in terminal but wont show anything in geektool… any suggestions?

  16. 17

    @Tross — If I had to guess what the problem is, it’d be that you are not currently supplying the full path name to the Python script in GeekTool. You need to do something like /path/to/file/weather.py 90024.

  17. 18

    Hi!

    Thanks for a great script! I live in Sweden and have som problems getting the script to show the forecast for my city. All i get now is Dallas TX. My zip code is 75258.

  18. 19

    Oh, never mind.

  19. 20

    @Fredric — Yeah, it’s kind of pain that you have to go look up your location code for non-US cities. You’d need to do something like /path/to/script/weather.py SWXX0040.

    I think it might be possible to write something to take a city and country and search the Yahoo! weather pages for its location ID, but I haven’t really looked into this.

    Did you end up getting it working correctly?

  20. 21

    Yeah, it works great for me now.

    But when i took the same script and used the same command in Geekttool on my girlfriend’s computer nothing shows up :S

    It works in the Terminal but when i call it from geektools its just blank.

    Ideas?

  21. 22

    @Fredric — Are you sure that you’re specifying the correct path in GeekTool?

    If weather.py is saved in ~/Documents, then you probably need to put /Users/<her username>/Documents/weather.py <location code> in the GeekTool Command window.

    That’s usually the problem that occurs when it works in the Terminal but not in GeekTool.

  22. 23

    I’ve written the exakt same line for her as i did for me. And my script works just fine. Confusing to say the least…

    I’ll see if i can figure something out later.

    Another question; is there a way to display the forecast even when you are offline?

  23. 24

    @Fredric

    Another question; is there a way to display the forecast even when you are offline?

    I’ve definitely thought about caching the forecast. I’ll let you know if and when I implement this.

  24. 25

    I’d really appreciate that!

    What if the script generated a text-file? And then you could just show the contents of that file in geektools?

    Now i have a script that does that with the weather image. (don’t know if geektools can print the content of a text.file though…)

  25. 26

    @Fredric — I have updated the weather script to allow the output of the weather conditions to a file. Now the command

    $ weather.py 24060 --output='weather.txt' && cat weather.txt
    

    will attempt to grab the latest weather conditions and write them to the contents of the file ‘weather.txt’. However, the file will not be overwritten if no report could be generated, so the file will preserve the latest weather conditions.

    You can download the latest version of the script at the top of this page or right here. Let me know if this works for you.

  26. 27

    Great!!!

    Works like a charm! Have you seen the script where you can grab the image from yahoo weather? They look beautifull together!

  27. 28

    [...] no question that my post that describes my script to get the current weather conditions with Python and Yahoo! weather feeds is the most popular post on my site. It drives a huge proportion of the (small amount of) traffic [...]

  28. 29

    This is classic asp script will allow you to monitor your current local weather via a Weather.com XML feed. It parses the XML data and then outputs formatted HTML. You need to acquire a Partner ID and License Key from Weather.com. This service is completely free, and they only want your email. Visit this URL to sign up.

  29. 30

    @Weather on your site — I don’t think you posted a proper link to the weather scripts site you mentioned. It does sound interesting though, so I’d appreciate it if you came back and posted it.

  30. 31

    I can get the script to work, i understand how to do the -v, -l, -c and have them display, or not display. However, I cant figure out how to make the -f work i’ve tried “-f 3″, “-f3″ neither seem to work for me. Also i cant figure out how to make the current day high,low and condition work. I would appreciate any help you could offer.

    Thanks, Eric

  31. 32

    @Eric — Unfortunately, Yahoo! only lets you get the forecast from their XML feeds for two days. An even more unfortunate fact is that the current day counts as the first day.

    So, python weather.py -f3 24060 won’t work, but -f1 and -f2 will. -f1 gives you today’s forecast and -f2 gives you today’s and tomorrow’s forecast.

    If you want the current day’s high and low temperatures, try python weather.py -f1 24060. If you want only that information, include the -n option, too.

  32. 33

    I found a Python script similar to my yweather.py…

    I found another Python script that gets weather from Yahoo, here: Yahoo! Weather Feeds With Python. And it’s open source :D At first I was disappointed, because I would’ve wanted to be the first one to do a script like this. But after this …

  33. 34

    Hi! Although you said the problem with the international codes was solved, the version I got today from GitHub still doesn’t work with WOEIDs longer than 5 chars.

    I needed to find a way to print the degree character a while ago. Here’s how:

    >>> n = u"\xb0"
    >>> print n
    >>> °

    Have a nice day!

  34. 35

    I am having a hell of a time trying to run this script. OS X 10.6.x MBP In terminal I “./weather.py 48413″ terminal responds with “-bash: ./weather.py: Permission denied”

    Any thoughts?

  35. 36

    @Aaron: It sounds like the script doesn’t have permission to execute. Type chmod +x weather.py in the same directory as the script.

    chmod controls file permissions; by giving it the argument +x, you are letting the OS know that it can execute the specified file in addition to reading and writing it.

  36. 37

    In Terminal I get the following error messages.

    ? any ideas …….

    Macintosh-201:~ howardm$ /Users/howardm/Documents/Scripts/weather.py 84103 /Users/howardm/Documents/Scripts/weather.py: line 6: !DOCTYPE: No such file or directory /Users/howardm/Documents/Scripts/weather.py: line 7: syntax error near unexpected token newline' /Users/howardm/Documents/Scripts/weather.py: line 7: “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>’

    ……..

    Thanks.

  37. 38

    @Howard: It looks like you saved the GitHub page for weather.py and not the script itself. Here’s the direct link to a zip archive that contains the latest version of the script. Unzip it and use the weather.py in there.

  38. 39

    [...] month, the long name of the month, and the time, as well as a pair of Python scripts to pull the local weather from Yahoo, and the number of unread messages in my Gmail inbox. They’re all sized [...]

Post a comment

Your email address is never shared. Required fields are marked with *.

*
*