Python 3.3.2 - trying to read url from wunderground
I have tried my best to try and convert the code from the old version of Python. I'm just trying to run api lookup from wunderground and I can't get past my errors in python. Here is the error: f = urllib.request.urlopen (filename) AttributeError: 'module' object has no attribute 'request'
The code is pretty straight forward, I know I am missing something simple, thanks for any help.
import urllib
import json
key = "xxxxxxxxxxxxxxxxx"
zip = input('For which ZIP code would you like to see the weather? ')
fileName = "http://api.wunderground.com/api/" + key + "/geolookup/conditions/q/PA/" + zip + ".json"
f = urllib.request.urlopen(fileName)
json_string = f.read()
parsed_json = json.loads(json_string)
location = parsed_json['location']['city']
temp_f = parsed_json['current_observation']['temp_f']
print ("Current temperature in %s is: %s % (location, temp_f)")
close()
source to share
Sometimes a package import (for example numpy
) will automatically import submodules (for example numpy.linalg
) into its namespace. But that doesn't apply to urllib
. Therefore you need to use
import urllib.request
instead
import urllib
to access the module urllib.request
. Alternatively, you can use
import urllib.request as request
to access the module as request
.
Looking at the examples in the docs is a good way to avoid similar problems in the future.
Since it f.read()
returns an object bytes
and json.loads
expects str
, you also need to decode the bytes. The exact encoding depends on what the server decides to send to you; in this case the bytes are utf-8
encoded. So use
json_string = f.read().decode('utf-8')
parsed_json = json.loads(json_string)
to decode bytes.
There is a typo on the last line. Use
print ("Current temperature in %s is: %s" % (location, temp_f))
to interpolate a string "Current temperature in %s is: %s"
with values (location, temp_f)
. Pay attention to the placement of the quotation mark.
Council. Since it zip
is a built-in function, it is good practice not to use a variable zip
, as this changes the normal value zip
, which makes it harder for others and possibly the future - you have to understand your code. The fix is easy: change zip
to something else like zip_code
.
import urllib.request as request
import json
key = ...
zip_code = input('For which ZIP code would you like to see the weather? ')
fileName = "http://api.wunderground.com/api/" + key + "/geolookup/conditions/q/PA/" + zip_code + ".json"
f = request.urlopen(fileName)
json_string = f.read().decode('utf-8')
parsed_json = json.loads(json_string)
location = parsed_json['location']['city']
temp_f = parsed_json['current_observation']['temp_f']
print ("Current temperature in %s is: %s" % (location, temp_f))
source to share
I would recommend using the Request Python HTTP Library for People. , the code below will work for either python2 or 3:
import requests
key = "xxxxxxxxxxx"
# don't shadow builtin zip function
zip_code = input('For which ZIP code would you like to see the weather? ')
fileName = "http://api.wunderground.com/api/{}/geolookup/conditions/q/PA/{}.json".format(key, zip_code)
parsed_json = requests.get(fileName).json()
location = parsed_json['location']['city']
temp_f = parsed_json['current_observation']['temp_f']
# pass actual variables and use str.format
print ("Current temperature in {} is: {}%f".format(location, temp_f))
Getting the json is simple requests.get(fileName).json()
, using str.format
is the preferred method and I find it less error prone, it is also much more functional compared to the old style formatting printf
.
You can see that it works with both 2 and 3 with a sample run:
:~$ python3 weat.py
For which ZIP code would you like to see the weather? 12212
Current temperature in Albany is: 68.9%f
:~$ python2 weat.py
For which ZIP code would you like to see the weather? 12212
Current temperature in Albany is: 68.9%f
source to share