我正在尝试开发一些涉及在两个地理位置之间找到距离的东西。
源和目标有很多这样的组合,我将它循环传入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
的情况下更好地纠正它。
答案 0 :(得分:1)
我认为主要问题源于代码格式不正确的事实。它现在的设置方式,我不相信你能够防止这个错误。
嵌套for循环
for i in geocodes:
for j in key_list:
geocodes
是包含原点和目标坐标的列表列表,key_lists
包含所有api密钥。这里的问题是geocodes
是第一个for
循环。实质上,key_list
中的每个键都用于查找每个坐标对的距离矩阵。哪个是浪费api资源。
使用不同的api密钥
api_url = base_url + origin_part + destination_part + key
这行代码属于嵌套的for
循环,并生成您的api url。问题在于它永远不会改变。最后一个元素是key
。既然你说这只是代码片段,我们不知道key
的含义是什么,但我认为它是一个在代码前面设置的静态api密钥。当它实际上应该是j
时,它会切换键。
按错键切换
if json_response["status"] == "OVER_QUERY_LIMIT":
j+=1
i-=1
这行代码并不完全符合你的想法。它不会切换到for循环中的下一个j
,然后返回i
。这只会从其值中加1或减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
请注意,我并不精通map API的合法用途。但是,我很确定您所做的事情违反了Google的条款和条件,使用多个帐户超出了您的每日限制使用率。
我建议在google开发者控制台上进行免费试用。他们为您提供300美元的信贷,使用他们的服务超出报价。
答案 1 :(得分:1)
正如其他回复中所述,您的摘录不是有效的代码,使用不同的密钥可能会滥用Google的T&amp; 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失败,但它们应该减少影响。