Python for Infomatics 第13章 网页服务四(译)

这几天因为其他事务,打断了自己的学习计划,今天继续我的翻译,避免又中途而废。

注:文章原文为Dr. Charles Severance 的 《Python for Informatics》。文中代码用3.4版改写,并在本机测试通过。

13.7 谷歌的 geocoding 网页服务

  谷歌公司有一个非常优秀的网页服务叫做geocoding。这个服务允许我们使用他们庞大的地理信息数据库。当我们向geocoding API提交一个"Ann Arbor, MI"的地理位置查找字符串后,谷歌将返回它推测出来的,在地图上可能找到搜索字符串的最佳地理位置,并告诉我们周边的地标。

  geocoding网页服务是免费的,但是为了防止盈利性程序无限制使用此API,它对速率进行了限制。如果你拥有的一些调查数据,是终端用户通过自由格式的输入框输入位置信息的,那么你可以利用这个API很好的整理你的数据。

  当你们使用类似像谷歌 geocoding 免费API时,你需要尊重使用这些资源。如果太多的人滥用这个服务,谷歌可能停止或者显著减少它的免费服务。

  你可以阅读这个服务的在线文档,但它非常简单,你甚至在你的浏览器中输入以下URL来测试它。
http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=Ann+Arbor%2C+MI

  在复制粘贴这个URL到你的浏览器之前,请确认解包和删除中间的任何空格。
  下面这个简单的程序,首先提示用户输入搜索的字符串,然后调用geocoding API,并从返回的JSON中抓取信息。
  

import urllib.request
import urllib.parse
import json

serviceurl='http://maps.googleapis.com/maps/api/geocode/json?'

while True:
    address = input('Enter location: ')
    if len(address) < 1 :
        break
    url = serviceurl + urllib.parse.urlencode({'sensor':'false','address':address})
    print('Receiving', url)
    try:
        uh = urllib.request.urlopen(url)
    except:
        print('Can not connect the server')
        break
    data = uh.read()
    print('Received',len(data),'characters')

    try:
        js = json.loads(data.decode('utf-8'))
    except:
        js = ''
    if 'status' not in js or js['status'] != 'OK':
        print('==== Failure To Retriev ====')
        print(data.decode('utf-8'))
        continue

    print(json.dumps(js, indent = 4))

    lat = js["results"][0]["geometry"]["location"]["lat"]
    lng = js["results"][0]["geometry"]["location"]["lng"]

    print('lat', lat, 'lng', lng)
    location = js['results'][0]['formatted_address']
    print(location)

  这个程序先获取查找字符串,然后创建一个URL,并将这个字符串进行适当编码作为参数包含在URL中,之后用urllib从geocoding API处获得文本信息。我们得到的数据依赖于我们发送的这个参数和存储在谷歌中的数据,而不是一个固定的网页。

  一旦我们获取了JSON数据,我们就可以用JSON库来分析它,并做一些检验,来确保我们获取的是正确的数据,然后我们抓取寻找的数据。

  程序的输出如下:

Enter location: china
Receiving http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=china
Received 1182 characters
{
    "results": [
        {
            "formatted_address": "China",
            "types": [
                "country",
                "political"
            ],
            "address_components": [
                {
                    "types": [
                        "country",
                        "political"
                    ],
                    "long_name": "China",
                    "short_name": "CN"
                }
            ],
            "geometry": {
                "viewport": {
                    "southwest": {
                        "lat": 18.1576156,
                        "lng": 73.4994136
                    },
                    "northeast": {
                        "lat": 53.56097399999999,
                        "lng": 134.7728099
                    }
                },
                "location_type": "APPROXIMATE",
                "bounds": {
                    "southwest": {
                        "lat": 18.1576156,
                        "lng": 73.4994136
                    },
                    "northeast": {
                        "lat": 53.56097399999999,
                        "lng": 134.7728099
                    }
                },
                "location": {
                    "lat": 35.86166,
                    "lng": 104.195397
                }
            },
            "place_id": "ChIJwULG5WSOUDERbzafNHyqHZU"
        }
    ],
    "status": "OK"
}
lat 35.86166 lng 104.195397
China

  你可以从www.py4inf.com/code下载geojson.py和geoxml.py,浏览比较谷歌geocoding API JSON格式和XML格式的区别。

(译者注:因为国际出口拥堵的原因,访问geocoding API成功率较低,需要多试几次)

原文地址:https://www.cnblogs.com/zhengsh/p/5459463.html