调用Nominatim API遇403禁止访问,求合规调用建议
解决Nominatim 403 Forbidden错误的合规方案
错误原因分析
触发403的核心原因是违反了Nominatim的使用政策,具体到你的代码问题:
- User-Agent不符合要求:你设置的
api_client过于通用,Nominatim要求User-Agent必须包含可联系的信息(如邮箱、项目网址),而非模糊标识,方便服务方在出现问题时联系到你。 - 自定义Header未生效:你定义的
$defaultHeader没有传入Guzzle Client或Nominatim实例,导致设置的User-Agent根本没被使用。 - 可能存在请求频率过高:公共Nominatim服务器限制单IP每秒最多1次请求,批量查询时如果没有间隔,会直接触发封禁。
- 使用HTTP协议:Nominatim官方推荐使用HTTPS而非HTTP,避免请求被拦截或降级。
合规调用修正方案
关键规则遵守
- 必须设置包含有效联系信息的User-Agent,比如
"MyGeocodingApp/1.0 (contact@myapp.com)" - 严格控制请求频率:单IP每秒最多1次请求,批量查询需设置至少1秒的间隔
- 使用HTTPS协议访问服务
- 避免不必要的重复请求,缓存查询结果
修正后的完整PHP代码
<?php use maxh\Nominatim\Nominatim; use GuzzleHttp\Client; $adresse = [ 'strasse' => $strasseXml, 'ort' => $datensatz['Ort'], 'plz' => $datensatz['PLZ'] ]; // 使用HTTPS协议 $url = "https://nominatim.openstreetmap.org/"; // 配置合规的Guzzle Client,核心是设置合法的User-Agent $client = new Client([ 'base_uri' => $url, 'timeout' => 30, 'connection_timeout' => 5, 'headers' => [ // 替换成你的项目名称和联系信息 'User-Agent' => 'MyGeocodingProject/1.0 (your-email@example.com)' ], // 建议开启SSL验证,除非你有特殊需求 'verify' => true ]); // 将自定义Client传入Nominatim实例,确保Header生效 $nominatim = new Nominatim($url, $client); $search = $nominatim->newSearch() ->street($adresse['strasse']) ->city($adresse['ort']) ->postalCode($adresse['plz']) ->country('Germany') ->addressDetails(); try { // 如果是批量查询,这里需要添加延迟 // sleep(1); // 批量请求时必须添加至少1秒间隔 $ergebnis = $nominatim->find($search); // 处理返回结果 print_r($ergebnis); } catch (\GuzzleHttp\Exception\ClientException $e) { echo "Fehlermeldung: " . $e->getMessage() . "\n"; echo "HTTP-Code: " . $e->getResponse()->getStatusCode() . "\n"; echo "Antwort: " . $e->getResponse()->getBody()->getContents() . "\n"; }
额外注意事项
- 批量查询处理:如果需要批量处理多个地址,必须在每个请求之间添加
sleep(1)甚至更长的间隔,避免触发速率限制。 - 结果缓存:对相同地址的查询结果进行缓存(比如存入数据库或文件),减少重复请求,既遵守规则又提升性能。
- 使用自有实例:如果你的请求量较大,建议搭建自己的Nominatim实例,避免依赖公共服务器的限制。
内容的提问来源于stack exchange,提问作者Thomas Kujawa
相关产品推荐
相关产品推荐

