使用PHP cURL下载带有特殊字符的URL

时间:2017-06-30 07:56:25

标签: php curl unicode web-scraping

我正在尝试使用PHP cURL下载以下网址https://www.astegiudiziarie.it/vendita-asta-appartamento-genova-via-san-giovanni-d’acri-14-1360824

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.astegiudiziarie.it/vendita-asta-appartamento-genova-via-san-giovanni-d’acri-14-1360824');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$f = curl_exec($ch);
curl_close($ch);
echo $f;

但服务器始终返回错误页面。在Web浏览器中导航相同的URL工作正常。手动将curl_exec返回的HTML源与Web浏览器中的HTML源进行比较,差异立即显着。

我尝试utf8_decode()网址但没有成功。

我不能简单地包装网址 在urlencode()中,因为它会对:/等普通字符进行编码。

这些URL是以编程方式(抓取)检索的,并且不会总是具有相同的结构,因此很难将它们拆分并且只对某些部分进行urlencode。

顺便说一下,现代网络浏览器似乎很好地处理了这种情况。在PHP中有一个解决方案吗?

4 个答案:

答案 0 :(得分:1)

您的网址已经过编码。由于服务器只解码了一次,因此不要将urlencode()作为404的原因调用。只需删除通话。

答案 1 :(得分:0)

解析网址组件,然后对其进行编码。

我们的想法是仅在路径上使用urlencode()并查询网址的部分内容,而只保留初始细分。我相信这就是浏览器在幕后所做的事情。

您可以使用parse_url()将URL拆分为其组件,转义您需要的部分(最有可能是路径和查询)并重新组合它。有人甚至在parse_url() documentation page的评论中发布了重新组合网址的功能。

答案 2 :(得分:0)

也许

$urli=parse_url('https://www.astegiudiziarie.it/vendita-asta-appartamento-genova-via-san-giovanni-d’acri-14-1360824');
$url=urli['scheme'].'://'.$urli['host'].'/'.urlencode(ltrim('/',$urli['path'])).'?'.$urli['query'];

答案 3 :(得分:0)

我终于结束了:

function urlencode_parts($url) {
    $parts = parse_url($url);
    $parts['path'] = implode('/', array_map('urlencode', explode('/', $parts['path'])));
    $url = new \http\Url($parts);
    return $url->toString();
}

使用包\http\Url,替换最新PHP版本中的http_build_url函数。

似乎file_get_contents对特殊字符也不起作用。

更新2018-05-09 :它似乎已在cUrl 7.52.1中修复