I'm trying to make a program that gets a country name, goes to restcountries.com, gets the country's current population number, does the same thing another time, and tells if the population got bigger/smaller/same. I am a beginner at python and coding, so existing answers to similar questions were not so useful to me since they seem different than my problem. I have managed to make the code get the JSON from the site, keep it, and tell me the population number and it worked (I tested it with "Israel". But when I gave it to my pal, he wrote "Russia" and it failed. After a short investigation, I discovered restcountries.com calls Russia by the name "Russian Federation" and has a separate JSON dictionary key for common names called "common:". But I can't get to it and extract it by code. Here is the JSON from this URL: https://restcountries.com/v3/name/russia?fields=name,population
[{"name":{"common":"Russia","official":"Russian Federation","nativeName":{"rus":{"official":"Российская Федерация","common":"Россия"}}},"population":144104080}]
Here is my current code:
import bs4
import urllib.request
import json
country_name = input("Choose country: ")
# Getting updated list and saving it as "json_data"
link = 'https://restcountries.com/v3/name/' country_name '?fields=name,population'
webpage = str(urllib.request.urlopen(link).read())
soup = bs4.BeautifulSoup(webpage, "html.parser")
json_data = soup.get_text()
# Cleans json_data from all the bullshit
clean_json = json_data[:-1][2:].replace('\\', '.') \
.replace('.xc3.x85', 'A').replace('.xc3.xa7', 'c').replace('.xc3.xa9', 'e')
# Convert clean_json to a dictionary
loaded_json = json.loads(clean_json)
# Country search function
def search(name):
for p in loaded_json:
if p['name'] == name:
return p['population']
# Choose Country, save data.
country_population = search(country_name)
datafile = open('G:\HackerU\Python\Challenges\Population\dataname.txt','w')
def save(done):
datafile = open('G:\HackerU\Python\Challenges\Population\dataname.txt','w')
datafile.write(country_population)
datafile.close()
return True
saved_population_number = datafile.read()
if saved_population_number > country_population:
print("Population number has been decreased.")
elif saved_population_number < country_population:
print("Population number has risen.")
elif saved_population_number == country_population:
print("Population number stayed the same.")
else:
print("Unknown Error.")
How do I make my code recognize a country only by its "common" name?
CodePudding user response:
It seems that there is a lot of unnecessary code here:
First of all, an API returns a JSON, therefore I don't see why you need to use bs4
. You can load the JSON into a dict
using json.loads
.
Secondly, you don't want a string representation of the bytes object - but to decode the bytes. Therefore you can use urllib.request.urlopen(req).read().decode()
.
Therefore I would do something like this:
import json
import urllib.request
country_name = input("Choose country: ")
req = 'https://restcountries.com/v3/name/' country_name '?fields=name,population'
response = json.loads(urllib.request.urlopen(req).read().decode())[0]
Now you have the JSON response in a dictionary, and accessing response['population]
gets you the country's population.
In addition, I would recommend learning about context managers and using them. For example, I would change the save
function to (also, why does it return True
?):
def save(country_population):
with open('G:\HackerU\Python\Challenges\Population\dataname.txt','w') as datafile:
datafile.write(country_population)
Good luck in the course, Python is a great language to start coding with.
CodePudding user response:
Your issue has to do with how the json data is formatted. Replace if p['name'] == name:
by if p['name']['common'] == name: