在 OSM Nominatim 的使用政策中规定,您需要提供 User-Agent 或 HTTP-Referer 请求标头来标识应用程序。因此,使用用户代理伪装成最终用户浏览器确实不是什么好礼节。
您可以找到使用政策here。它还说 http 库使用的默认值(如 simplexml_load_file() 使用的那个)是不可接受的。
您说您正在使用simplexml_load_string(),但没有说明您是如何将 XML 获取到该函数的。但最有可能的情况是,无论您使用哪种方法获取 XML 文件,您都忽略了传递强制标头。
因此,我将使用php-curl 创建一个请求,提供这些标头之一来标识您的应用;并使用 simplexml_parse_string() 解析生成的 XML 字符串。
例如:
// setup variables
$nominatim_url = 'https://nominatim.openstreetmap.org/search?postalcode=28217&country=DE&format=xml&polygon=1&addressdetails=1&boundary=postalcode';
$user_agent = 'ID_Identifying_Your_App v100';
$http_referer = 'http://www.urltoyourapplication.com';
$timeout = 10;
// curl initialization
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $nominatim_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
// this is are the bits you are missing
// Setting curl's user-agent
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
// you an also use this one (http-referer), it's up to you. Either one or both.
curl_setopt($ch, CURLOPT_REFERER, $http_referer);
// get the XML
$data = curl_exec($ch);
curl_close($ch);
// load it in simplexml
$xml = simplexml_load_string($data);
// This was your code, left as it was
if (false === $xml) {
$errors = libxml_get_errors();
var_dump($errors);
}