获取一个城市的人口给它的名字

Posted

技术标签:

【中文标题】获取一个城市的人口给它的名字【英文标题】:Getting the population of a city given its name 【发布时间】:2017-07-09 04:25:00 【问题描述】:

我可以使用什么好的 Python API 来获取城市人口?我曾尝试使用地理编码器,但它不工作 - 不知道为什么。

geocoder.population('San Francisco, California')

返回

'module' object has no attribute 'population'

为什么会发生这种情况,我该如何解决?

或者,我可以为此使用不同的 python api 吗?

【问题讨论】:

不确定为什么要为此构建 API...dict 就是将字符串映射到数字所需的全部内容。 不尝试构建 API,我想找到一个可以为我获取人口的 API... 【参考方案1】:

当然,您可以使用地理编码器和 Google 获取城市的人口信息, 但它需要API key。

这里有两种完全不同的替代解决方案:

OpenDataSoft

第一个解决方案使用 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 从中提取所需的信息。

希望有帮助!

【讨论】:

解决方案 1 (OpenDataSoft) 是否可以使用完整的国家名称而不是缩写 ('de', 'en', ...)?我只有 Cities and the Country 全名。 您能否也给我一个提示,您是如何连接动态链接的?我在该网站上找不到如何定义自己的请求链接的任何信息。他们总是引用他们的 API 我对 OpenDataSoft 了解不多,这里解释了(一点)API:help.opendatasoft.com/apis/ods-search-v1/#dataset-search-api 我的示例查询只返回“de”而不是“Germany”或“Deutschland”,显然那些不能在请求中使用。在浏览器中打开:public.opendatasoft.com/api/records/1.0/search/… API/地址字符串的一些有用组件:&q=berlin(全文搜索)、facet=country&refine.country=de(国家过滤器)、&facet=city&refine.city=berlin(城市过滤器) 【参考方案2】:
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))

非常感谢之前的回答。我也必须解决这个问题。我上面的代码来自上面大卫的回答,他推荐了 OpenDataSoft API。显然,此时的 Google API 不提供人口结果。

我在下面使用的代码能够获取城市人口,OpenDataSoft 并不总是返回城镇人口。

我的代码结合了我在 *** 上找到的不同问题的几个答案的代码。

您将需要获得一个谷歌地图开发者 API 密钥,并进行相关的 pip 安装。

    首先,此代码获取任何地名的经纬度坐标 基于用户输入 然后它使用这些从谷歌地图上获取国家/地区名称 然后它使用国家名称来获取缩写的2 国家的信件 然后它发送地名和缩写的 2 个字母从 OpenDataSoft 获取人口

【讨论】:

以上是关于获取一个城市的人口给它的名字的主要内容,如果未能解决你的问题,请参考以下文章

从哪里获取有关所有欧洲城市、村庄的数据?

TextView 没有保留我给它的值

位置数据,用于我自己的数据库 - mysql

如何从演员本身中获取 Akka 演员的名字?

字典和循环

输入城市名称并获取可能城市列表的 API? [关闭]