使用GeoDjango获取双位置时遭遇GeocoderUnavailable错误求助
我在使用GeoDjango开发两地位置信息获取功能时,访问根路径遇到错误:GeocoderUnavailable at /,相关视图代码如下:
from django.shortcuts import render, get_object_or_404 from .models import Measurement from .forms import MeasurementModelForm from geopy.geocoders import Nominatim from geopy.distance import geodesic from .utils import get_geo, get_center_coordinates, get_zoom import folium # Create your views here. def calculate_distance_view(request): # initial values distance = None destination = None obj = get_object_or_404(Measurement, id=1) form = MeasurementModelForm(request.POST or None) geolocator = Nominatim(user_agent='measurements') ip = '72.14.207.99' country, city, lat, lon = get_geo(ip) location = geolocator.geocode(city) # location coordinates l_lat = lat l_lon = lon pointA = (l_lat, l_lon) # initial folium map m = folium.Map(width=800, height=500, location=get_center_coordinates(l_lat, l_lon), zoom_start=8) # location marker folium.Marker([l_lat, l_lon], tooltip='click here for more', popup=city['city'], icon=folium.Icon(color='purple')).add_to(m) if form.is_valid(): instance = form.save(commit=False) destination_ = form.cleaned_data.get('destination') destination = geolocator.geocode(destination_) # destination coordinates d_lat = destination.latitude d_lon = destination.longitude pointB = (d_lat, d_lon) # distance calculation distance = round(geodesic(pointA, pointB).km, 2) # folium map modification m = folium.Map(width=800, height=500, location=get_center_coordinates(l_lat, l_lon, d_lat, d_lon), zoom_start=get_zoom(distance)) # location marker folium.Marker([l_lat, l_lon], tooltip='click here for more', popup=city['city'], icon=folium.Icon(color='purple')).add_to(m) # destination marker folium.Marker([d_lat, d_lon], tooltip='click here for more', popup=destination, icon=folium.Icon(color='red', icon='cloud')).add_to(m) # draw the line between location and destination line = folium.PolyLine(locations=[pointA, pointB], weight=5, color='blue') m.add_child(line) instance.location = location instance.distance = distance instance.save() m = m._repr_html_() context = { 'distance' : distance, 'destination': destination, 'form': form, 'map': m, } return render(request, 'measurements/main.html', context)
错误原因分析
GeocoderUnavailable错误表示无法连接到Nominatim地理编码服务,常见诱因:
- 网络问题导致无法访问Nominatim服务器
- 请求频率过高触发Nominatim的限流机制
- User-Agent设置不规范被服务拦截
- 服务临时维护或故障
解决办法
1. 添加异常捕获,避免程序崩溃
在调用geolocator.geocode()的位置增加异常处理,即使服务不可用也能返回友好响应:
from geopy.exc import GeocoderUnavailable, GeocoderTimedOut # ... 其他代码 ... # 处理初始位置的地理编码 try: location = geolocator.geocode(city) except (GeocoderUnavailable, GeocoderTimedOut): location = None # 可以在context中添加错误提示,前端显示给用户 # 处理表单提交后的目标位置地理编码 if form.is_valid(): instance = form.save(commit=False) destination_ = form.cleaned_data.get('destination') try: destination = geolocator.geocode(destination_) except (GeocoderUnavailable, GeocoderTimedOut): destination = None # 同样添加错误提示到context
2. 规范Nominatim请求配置
- 设置合规的User-Agent:Nominatim要求User-Agent包含项目信息和联系方式,避免被拦截
geolocator = Nominatim(user_agent="your-project-name/1.0 (your-contact-email@example.com)")
- 添加请求延迟:Nominatim限制每秒最多1次请求,添加延迟避免触发限流
from time import sleep # 在每次geocode请求后添加延迟 location = geolocator.geocode(city) sleep(1)
3. 检查网络连通性
确认服务器可以访问https://nominatim.openstreetmap.org/,国内服务器可能需要配置代理才能正常访问。
4. 切换备用地理编码服务
如果Nominatim稳定性无法满足需求,可以考虑使用其他服务,比如Google Geocoding API或Mapbox Geocoding API(需申请API密钥)。
内容的提问来源于stack exchange,提问作者Rashid Khan
相关产品推荐
相关产品推荐

