使用bing或google API在Python中获取位置坐标

3

我有一个样本文本文件,其中存储了通过爬取各种html页面获得的文本数据。这个文本包含有关各种事件及其时间和地点的信息。我想获取这些地点的坐标。我不知道如何在Python中实现这一点。我正在使用nltk识别此示例文本中的命名实体。以下是代码:

import nltk

with open('sample.txt', 'r') as f:
    sample = f.read()

sentences = nltk.sent_tokenize(sample)
tokenized_sentences = [nltk.word_tokenize(sentence) for sentence in sentences]
tagged_sentences = [nltk.pos_tag(sentence) for sentence in tokenized_sentences]
chunked_sentences = nltk.batch_ne_chunk(tagged_sentences, binary=True)

#print chunked_sentences
#print tokenized_sentences
#print tagged_sentences

def extract_entity_names(t):
    entity_names = []

    if hasattr(t, 'node') and t.node:
        if t.node == 'NE':
            entity_names.append(' '.join([child[0] for child in t]))
        else:
            for child in t:
                entity_names.extend(extract_entity_names(child))

    return entity_names

entity_names = []
for tree in chunked_sentences:
    # Print results per sentence
    # print extract_entity_names(tree)

    entity_names.extend(extract_entity_names(tree))

# Print all entity names
#print entity_names

# Print unique entity names
print set(entity_names)

样例文件大致如下:

科文特花园的波西米亚人

时间:2013年1月18日(各种日期),晚上7:30。地点:伦敦科文特花园,约翰·科普利永久受欢迎的皇家歌剧制作普契尼的波西米亚人重新上演,恰好是在圣诞节期间的第一次。马克·埃尔德爵士指挥罗兰多·维拉佐恩饰演罗杜尔福和麦加·科瓦列夫斯卡饰演米蜜。米蜜在巴黎拉丁区的一个寒冷的圣诞前夕遇到了诗人罗杜尔福(德米特罗·波波夫在1月5日和18日扮演这个角色)。在蜡烛熄灭后摸索着黑暗中,他们相爱了。罗杜尔福与其他三个小伙伴住在一起:哲学家柯林(纳欧尔·迪皮耶罗/金志勋在1月18日扮演)、音乐家肖那德(大卫·比兹)和画家马塞洛(奥德恩·伊维尔森),他爱上了穆塞塔(斯特法尼娅·多夫汉)。两对情侣分手,歌剧以罗杜尔福在一个冰冷的阁楼里发现米蜜患有结核病而死亡的悲剧结束。

我想从这段文本中获取伦敦科文特花园的坐标。我该怎么做?


3
你确实应该提到,“你”的代码只是 https://gist.github.com/322906 上示例代码的复制。 - jimhark
3个回答

6
自2013年9月起,Google Maps API v2 不再使用。这里是伟大的@jimhark代码的更新版本,适用于API v3(我省略了__main__部分):
import urllib
import simplejson

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

def get_coordinates(query, from_sensor=False):
    query = query.encode('utf-8')
    params = {
        'address': query,
        'sensor': "true" if from_sensor else "false"
    }
    url = googleGeocodeUrl + urllib.urlencode(params)
    json_response = urllib.urlopen(url)
    response = simplejson.loads(json_response.read())
    if response['results']:
        location = response['results'][0]['geometry']['location']
        latitude, longitude = location['lat'], location['lng']
        print query, latitude, longitude
    else:
        latitude, longitude = None, None
        print query, "<no results>"
    return latitude, longitude

查看 官方文档 获取完整的参数列表和其他信息。

5

你真正有两个问题:

  1. 如何提取位置文本(或潜在的位置文本)。
  2. 如何通过调用地理编码服务获取位置(纬度,经度)。

我可以帮助解决第二个问题。(但请参阅以下编辑以获取第一个问题的帮助。)

使用旧版Google Maps API(仍在工作中),您可以将地理编码缩短为一行(一行丑陋的代码):

def geocode(address):
    return tuple([float(s) for s in list(urllib.urlopen('http://maps.google.com/maps/geo?' + urllib.urlencode({'output': 'csv','q': address})))[0].split(',')[2:]])

请查阅Google Maps API Geocoding文档

以下是易读的7行版本及一些包装代码(当从命令行调用时,请记得用引号括起地址):

import sys
import urllib

googleGeocodeUrl = 'http://maps.google.com/maps/geo?'

def geocode(address):
    parms = {
        'output': 'csv',
        'q': address}

    url = googleGeocodeUrl + urllib.urlencode(parms)
    resp = urllib.urlopen(url)
    resplist = list(resp)
    line = resplist[0]
    status, accuracy, latitude, longitude = line.split(',')
    return latitude, longitude

def main():
    if 1 < len(sys.argv):
        address = sys.argv[1]
    else:
        address = '1600 Amphitheatre Parkway, Mountain View, CA 94043, USA'

    coordinates = geocode(address)
    print coordinates

if __name__ ==  '__main__':
    main()

解析CSV格式很简单,但XML格式具有更好的错误报告。

编辑 - 帮助您的第一个问题

我研究了 nltk。它并不简单,但我可以推荐自然语言工具包文档,CH 7-从文本中提取信息,特别是7.5 名称实体识别。在该部分结束时,他们指出:

NLTK提供了一个分类器,已经训练好以识别命名实体,可以通过函数nltk.ne_chunk()进行访问。如果我们设置参数binary=True,则命名实体只是标记为NE;否则,分类器添加类别标签,例如PERSON、ORGANIZATION和GPE。

您正在指定True,但您可能想要类别标签,因此:

chunked_sentences = nltk.batch_ne_chunk(tagged_sentences)

这提供了类别标签(命名实体类型),看起来很有前途。但在对您的文本和一些简单的位置短语进行尝试后,很明显需要更多规则。阅读文档以获取更多信息。


1
@AnshuThakur,你有什么建议可以让我的回答更容易接受吗? - jimhark

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接