Python调用Google Maps Geocode API仅返回1条结果,预期为2条
看起来你遇到了一个挺让人困惑的问题——同一个Geocode API请求URL,在Chrome里能返回2条结果,但Python脚本调用时只拿到1条。我来帮你拆解可能的原因和对应的解决办法:
1. 请求头差异(最可能的元凶)
浏览器发送请求时,会自动带上标识自身的User-Agent头,而requests库默认的请求头是python-requests/x.x.x这种格式。Google的Geocode API可能会根据请求来源的不同,调整返回结果的数量、排序甚至过滤规则,以此区分自动化请求和人工浏览请求。
解决办法:模拟浏览器的User-Agent
在requests.get请求中添加headers参数,把请求伪装成浏览器:
import requests # 模拟Chrome浏览器的User-Agent headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } # 修改请求部分 req = requests.get(GOOGLE_MAPS_API_URL, params=params, headers=headers)
2. 地址参数的编码差异
你手动请求的URL里,地址是LES+ARCS(用+代替空格),而requests库默认会把空格转成%20。虽然这两种编码在URL中都表示空格,但Google API对这两种编码的处理可能存在细微差异,导致返回结果不同。
解决办法:统一地址编码格式
可以用urllib.parse.quote()手动对地址进行URL编码,确保和浏览器的编码方式一致:
from urllib.parse import quote # 构造参数时对地址编码 params = { 'address': quote(row[1]), 'sensor': 'false', 'region': 'fr', # 'key' : 'AIzaSyA-lKrpRzcNzr2KSReq_UAq3niN01CBPdQ' }
3. API Key的影响
虽然你提到脚本没有API key也能运行,但使用API key和未授权请求的返回策略可能不同。未授权的请求可能会被限制结果数量,或者返回的结果优先级有差异。建议尝试添加你的API key到请求中,看看结果是否和浏览器一致。
4. 代码逻辑的潜在问题
你的代码目前只处理了res['results'][0],也就是第一条结果——哪怕脚本实际拿到了2条结果,你也只会处理第一条。另外,错误处理逻辑里,当遇到ZERO_RESULTS时循环请求是没有意义的,应该直接跳过这条记录。
优化后的结果处理逻辑:
if res['status'] == "OK": # 遍历所有返回结果 for result in res['results']: lat = result['geometry']['location']['lat'] lng = result['geometry']['location']['lng'] count += 1 # 插入数据库的逻辑 RS_replace = addslashes.addslashes(row[0]) VL_replace = addslashes.addslashes(row[1]) MysqlConnect.curs.execute( "INSERT INTO `temp` VALUES ('%s','%s','%s','%f','%d','%f','%f')" % (RS_replace, VL_replace, row[2], row[3], row[4], lat, lng) ) MysqlConnect.cnt.commit() elif res['status'] == "OVER_QUERY_LIMIT": # 仅在请求超限等待重试 time.sleep(2) # 加个等待时间,避免频繁请求 # 可以在这里重新发起请求 elif res['status'] in ["ZERO_RESULTS", "REQUEST_DENIED", "INVALID_REQUEST", "UNKNOWN_ERROR"]: print(f"处理地址 {row[1]} 时出错:{res['status']}") continue # 跳过当前记录
验证步骤
在修改代码后,可以先在循环里添加一行打印,确认脚本拿到的结果数量:
res = req.json() print(f"地址 {row[1]} 返回结果数量:{len(res.get('results', []))}")
这样你就能直观看到脚本是否拿到了2条结果,再针对性调整逻辑。
内容的提问来源于stack exchange,提问作者Antoine_Chabert

