【问题标题】:Connection Error while using requests to get response from google distance matrix api使用请求从谷歌距离矩阵 api 获取响应时出现连接错误
【发布时间】:2018-01-10 18:35:12
【问题描述】:

我正在尝试开发一些涉及查找两个地理位置之间的距离的东西。

有很多这样的源和目标组合,我将它们循环传递给 google distance API。

我的部分代码:

key_list = [****,****,....]  #google key list
base_url = 'https://maps.googleapis.com/maps/api/distancematrix/json?'

for i in geocodes:
    for j in key_list:

        origin_part = 'origins=' + i[0] + "," + i[1]
        destination_part = '&destinations=' + i[2] + "," + i[3]
        api_url = base_url + origin_part + destination_part + key
        json_response = requests.get(api_url,timeout=10).json()
        if json_response["status"] == "OVER_QUERY_LIMIT":
            j += 1
            i -= 1

这只是我代码的一部分。

geocodes 是一个包含子列表的嵌套列表

[[source_latitude,source_longitude,destination_latitude,destination_longitude],....]

代码运行良好一段时间,但一段时间后,它给我一个错误说:

HTTPSConnectionPool(host='maps.googleapis.com', port=443): Max retries exceeded with url: /maps/api/distancematrix/json?origins=xx,xx&destinations=xx,xx&key=xxxxx 
(Caused by NewConnectionError('<requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x7f53350c50f0>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution',))

我也尝试使用会话而不是请求,但同样的错误即将到来。

我想知道是什么导致了这个问题?

我怎样才能纠正它,最好不使用try-catch。

【问题讨论】:

  • 有多少目的地/来源?请提供一个 minimal reproducible example 来证明问题
  • @geocodezip 大约要计算 10 万个距离,但错误在 1000-2000 行之后随机出现,在计算多少距离后可能会出现错误并没有具体说明。
  • 您有完全访问 google maps api 的权限吗?还是您只使用免费版本?
  • 检查你是否在谷歌控制台的OVER_QUERY_LIMIT中。

标签: python python-3.x google-maps-api-3 python-requests google-distancematrix-api


【解决方案1】:

正如在其他回复中已经指出的那样,您的摘录不是有效的代码,并且使用不同的密钥可能是在滥用 Google 的 T's & C's。然而,这不是问题。

有什么问题?

requests 错误中非常清楚地说明了您的问题。如您所见,您在 urllib3 中遇到的错误是 here。您甚至还没有到向 Google 发送任何数据的地步。

查看特定消息 ([Errno -3] Temporary failure in name resolution),系统告诉您 DNS 无法将您的主机名 ("maps.googleapis.com") 解析为 IP 地址。

这是一个众所周知的功能,requests(通过urllib3)总是调用getaddrinfo 来解析主机名,所以要么你的操作系统没有缓存结果,要么你的DNS 服务器不稳定。详情请见this SO thread。

该怎么办?

第一个选择是尝试更可靠的 DNS 服务器 - 许多人在遇到此类问题时使用 Google 的 public DNS。

如果这不起作用,您可以尝试自己进行 DNS 查找(即调用 getaddrinfo)并在您的应用程序中缓存 IP 地址(然后使用它而不是 URL 中的主机名),或者您可以在您的计算机上安装 DNS 缓存。这些不会防止 DNS 故障,但它们应该会减少影响。

【讨论】:

    【解决方案2】:

    我认为主要问题源于代码格式错误。现在的设置方式,我不相信你能阻止这个错误。

    1. 嵌套for循环

      for i in geocodes:
          for j in key_list:
      

      geocodes 是包含起点和终点坐标的列表,key_lists 包含所有 api 密钥。这里的问题是geocodes 是第一个for 循环。从本质上讲,key_list 中的每个键都用于查找每个坐标对的距离矩阵。这是在浪费 api 资源。

    2. 不同api键的使用

      api_url = base_url + origin_part + destination_part + key
      

      这行代码位于您的嵌套for 循环中,并生成您的api url。这里的问题是它永远不会改变。最后一个元素是key。既然你说这只是代码的一个 sn-p,我们不知道key 是什么意思,但是我假设它是一个在代码前面设置的静态 api 密钥。当它实际上应该是j 时,它会切换键。

    3. 按键开启错误

      if json_response["status"] == "OVER_QUERY_LIMIT":
          j+=1
          i-=1
      

      这行代码并不完全按照您的想法运行。它不会转移到 for 循环中的下一个j,而是返回i。这只会从它们的值中加或减 1,因为没有 ints 或 floats 最终会引发错误。

    相反,我建议您将代码更改为此。

    base_url = 'https://maps.googleapis.com/maps/api/distancematrix/json?'
    key_list = [****,****,....]  #google key list
    
    index,atEnd = 0,False
    for coords in geocodes:
        origin_part = 'origins=' + coords[0] + "," + coords[1]
        destination_part = '&destinations=' + coords[2] + "," + coords[3]
        api_url = base_url + origin_part + destination_part + key_list[index]
        json_response = requests.get(api_url,timeout=10).json()
    
        #Check if your over your daily limit, if so try the next key
        while json_response['status'] == 'OVER_QUERY_LIMIT':
            index += 1
             #if all keys used to max quotas, exit
            if index == len(key_list):
                atEnd = True
                break
            api_url = base_url + origin_part + destination_part + key_list[index]
            json_response = requests.get(api_url, timeout=10).json()
        print json_response
    
        #Exit main loop if all quotas reached
        if atEnd == True:
            print'All of your keys quotas have been used, try again tomorrow'
            break
    

    请注意,我并不精通地图 API 的合法用途。但是,我很确定您的行为违反了 Google 的条款和条件,即使用多个帐户超出了您的每日使用限额。

    我建议在 google 开发者控制台上进行免费试用。他们为您提供 300 信用额度,以使用他们的服务超越报价。

    【讨论】:

      猜你喜欢
      • 2017-10-03
      • 1970-01-01
      • 2017-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多