有哪些好的Python API可以用来获取一个城市的人口?我尝试使用geocoder,但它没有工作-不确定为什么。
geocoder.population('San Francisco, California')
返回
'module' object has no attribute 'population'
为什么会发生这种情况,我该如何修复它?
或者,有没有其他可以用于此的不同 Python API?
有哪些好的Python API可以用来获取一个城市的人口?我尝试使用geocoder,但它没有工作-不确定为什么。
geocoder.population('San Francisco, California')
返回
'module' object has no attribute 'population'
为什么会发生这种情况,我该如何修复它?
或者,有没有其他可以用于此的不同 Python API?
这里有两种截然不同的替代解决方案:
第一种解决方案使用OpenDataSoft API和基本的Python 3。
需要通过一个两个字母的国家代码指定国家,请参见下面的示例。
import requests
import json
def get_city_opendata(city, country):
tmp = 'https://public.opendatasoft.com/api/records/1.0/search/?dataset=worldcitiespop&q=%s&sort=population&facet=country&refine.country=%s'
cmd = tmp % (city, country)
res = requests.get(cmd)
dct = json.loads(res.content)
out = dct['records'][0]['fields']
return out
get_city_opendata('Berlin', 'de')
#{'city': 'berlin',
# 'country': 'de',
# 'region': '16',
# 'geopoint': [52.516667, 13.4],
# 'longitude': 13.4,
# 'latitude': 52.516667,
# 'accentcity': 'Berlin',
# 'population': 3398362}
get_city_opendata('San Francisco', 'us')
#{'city': 'san francisco',
# 'country': 'us',
# 'region': 'CA',
# 'geopoint': [37.775, -122.4183333],
# 'longitude': -122.4183333,
# 'latitude': 37.775,
# 'accentcity': 'San Francisco',
# 'population': 732072}
第二个解决方案使用WikiData API和qwikidata软件包。
在这里,国家将以其英文名称(或部分名称)给出,如下面的示例所示。
我相信SPARQL命令可以写得更加高效和优雅(请随意编辑),但它可以完成工作。
import qwikidata
import qwikidata.sparql
def get_city_wikidata(city, country):
query = """
SELECT ?city ?cityLabel ?country ?countryLabel ?population
WHERE
{
?city rdfs:label '%s'@en.
?city wdt:P1082 ?population.
?city wdt:P17 ?country.
?city rdfs:label ?cityLabel.
?country rdfs:label ?countryLabel.
FILTER(LANG(?cityLabel) = "en").
FILTER(LANG(?countryLabel) = "en").
FILTER(CONTAINS(?countryLabel, "%s")).
}
""" % (city, country)
res = qwikidata.sparql.return_sparql_query_results(query)
out = res['results']['bindings'][0]
return out
get_city_wikidata('Berlin', 'Germany')
#{'city': {'type': 'uri', 'value': 'http://www.wikidata.org/entity/Q64'},
# 'population': {'datatype': 'http://www.w3.org/2001/XMLSchema#decimal',
# 'type': 'literal',
# 'value': '3613495'},
# 'country': {'type': 'uri', 'value': 'http://www.wikidata.org/entity/Q183'},
# 'cityLabel': {'xml:lang': 'en', 'type': 'literal', 'value': 'Berlin'},
# 'countryLabel': {'xml:lang': 'en', 'type': 'literal', 'value': 'Germany'}}
get_city_wikidata('San Francisco', 'America')
#{'city': {'type': 'uri', 'value': 'http://www.wikidata.org/entity/Q62'},
# 'population': {'datatype': 'http://www.w3.org/2001/XMLSchema#decimal',
# 'type': 'literal',
# 'value': '805235'},
# 'country': {'type': 'uri', 'value': 'http://www.wikidata.org/entity/Q30'},
# 'cityLabel': {'xml:lang': 'en', 'type': 'literal', 'value': 'San Francisco'},
# 'countryLabel': {'xml:lang': 'en',
# 'type': 'literal',
# 'value': 'United States of America'}}
这两种方法都会返回字典。你可以使用基本的Python语法从中提取所需的信息。
希望对你有帮助!
from urllib.request import urlopen
import json
import pycountry
import requests
from geopy.geocoders import Nominatim
def get_city_opendata(city, country):
tmp = 'https://public.opendatasoft.com/api/records/1.0/search/?dataset=worldcitiespop&q=%s&sort=population&facet=country&refine.country=%s'
cmd = tmp % (city, country)
res = requests.get(cmd)
dct = json.loads(res.content)
out = dct['records'][0]['fields']
return out
def getcode(cc):
countries = {}
for country in pycountry.countries:
countries[country.name] = country.alpha_2
codes = countries.get(cc)
return codes
def getplace(lat, lon):
key = "PUT YOUR OWN GOOGLE API KEY HERE" #PUT YOUR OWN GOOGLE API KEY HERE
url = "https://maps.googleapis.com/maps/api/geocode/json?"
url += "latlng=%s,%s&sensor=false&key=%s" % (lat, lon, key)
v = urlopen(url).read()
j = json.loads(v)
components = j['results'][0]['address_components']
country = town = None
for c in components:
if "country" in c['types']:
country = c['long_name']
if "postal_town" in c['types']:
town = c['long_name']
return town, country
address= input('Input an address or town name\t')
geolocator = Nominatim(user_agent="Your_Name")
location = geolocator.geocode(address)
locationLat = location.latitude
locationLon = location.longitude
towncountry = getplace(location.latitude, location.longitude)
mycity = towncountry[0]
mycountry = towncountry[1]
print(towncountry)
print(mycountry)
print(mycity)
mycccode = getcode(mycountry)
mycccode = mycccode.lower()
print(mycccode)
populationdict = get_city_opendata(address, mycccode)
population = populationdict.get('population')
print('population',population)
print(location.address)
print((location.latitude, location.longitude))
我非常感谢之前的答案。我也必须解决这个问题。 我上面的代码是从David的答案中继承而来的,他推荐使用OpenDataSoft API。 显然,谷歌API目前不提供人口结果。
我下面使用的代码能够获得城市的人口,但是OpenDataSoft并不总是返回城镇人口。
我的代码结合了我在stackoverflow上找到的一些不同问题的答案。
您需要获取谷歌地图开发者API密钥,并进行相关的pip安装。
dict
就足以将字符串映射到数字。 - Kevin J. Chase