如何使用 cURL 获取目标 URL?
Posted
技术标签:
【中文标题】如何使用 cURL 获取目标 URL?【英文标题】:How can I get the destination URL using cURL? 【发布时间】:2010-11-29 04:05:12 【问题描述】:当 HTTP 状态码为 302 时,
<?php
$url = "http://www.ecs.soton.ac.uk/news/";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$html = curl_exec($ch);
$status_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if($status_code=302 or $status_code=301)
$url = "";
// I want to to get the destination url
curl_close($ch);
?>
【问题讨论】:
其他未解决的问题有什么好运气吗? 你应该接受正确答案(-1) 【参考方案1】:你可以使用:
echo curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
【讨论】:
这种方法比从 Location 标头中解析出 url 要干净得多/通常更好。 CURLINFO_EFFECTIVE_URL 为我返回当前(请求的)页面。 curl_getinfo 结果中没有重定向 (Location:) url。看来,解析标头是最好的做法......CURLINFO_EFFECTIVE_URL
在某些情况下并不总是有效,尤其是那些不使用标头重定向的情况。
对于那些正在获取当前(请求)页面的人,在调用 curl_exec($ch); 后使用此代码
很好,比自己解析要干净得多。感谢分享!【参考方案2】:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, TRUE); // We'll parse redirect url from header.
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE); // We want to just get redirect url but not to follow it.
$response = curl_exec($ch);
preg_match_all('/^Location:(.*)$/mi', $response, $matches);
curl_close($ch);
echo !empty($matches[1]) ? trim($matches[1][0]) : 'No redirect found';
【讨论】:
完美!感谢分享 如果没有位置标头? 有时网站会使用元重定向或window.location.replace
来重定向页面。在这种情况下,请替换正则表达式以捕获结果。【参考方案3】:
回复有点过时,但想展示一个完整的工作示例,其中一些解决方案是:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); //set url
curl_setopt($ch, CURLOPT_HEADER, true); //get header
curl_setopt($ch, CURLOPT_NOBODY, true); //do not include response body
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //do not show in browser the response
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //follow any redirects
curl_exec($ch);
$new_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); //extract the url from the header response
curl_close($ch);
这适用于任何重定向,例如 301 或 302,但是在 404 上它只会返回请求的原始 url(因为它没有找到)。这可用于更新或删除您网站上的链接。无论如何,这是我的需要。
【讨论】:
【参考方案4】:您必须获取重定向 URL 的 Location 标头。
【讨论】:
这需要进一步的麻烦,比如检查它是否是相对的,解决它(如果有多个等,则在中间重定向中可能是以前的基本 URL 等。pp。),它更容易使用@ 987654321@.【参考方案5】:作为对 user437797 对 Tamik Soziev 回答的评论的回应(不幸的是,我没有直接在那里发表评论的声誉):
CURLINFO_EFFECTIVE_URL 可以正常工作,但要按照操作的要求进行操作,您当然还必须将 CURLOPT_FOLLOWLOCATION 设置为 TRUE。这是因为 CURLINFO_EFFECTIVE_URL 准确地返回它所说的,最终被加载的有效 url。如果您不遵循重定向,那么这将是您请求的 url,如果您遵循重定向,那么它将是重定向到的最终 url。
这种方法的好处是它也适用于多个重定向,而当您自己检索和解析 HTTP 标头时,您可能必须在最终目标 URL 公开之前多次执行此操作。
另请注意,curl 遵循的最大重定向数可以通过 CURLOPT_MAXREDIRS 控制。默认情况下它是无限制的(-1),但如果有人(可能是故意)为某些 url 配置了无限的重定向循环,这可能会给您带来麻烦。
【讨论】:
【参考方案6】:302 重定向的新目的地位于 http 标头字段“位置”中。 示例:
HTTP/1.1 302 Found
Date: Tue, 30 Jun 2002 1:20:30 GMT
Server: Apache
Location: http://www.foobar.com/foo/bar
Content-Type: text/html; charset=iso-8859-1
只需用正则表达式 grep 即可。
要包含所有 HTTP 标头信息,请使用 curl 选项 CURLOPT_HEADER 将其包含到结果中。设置它:
curl_setopt($c, CURLOPT_HEADER, true);
如果您只是想让 curl 跟随重定向,请使用 CURLOPT_FOLLOWLOCATION:
curl_setopt($c, CURLOPT_FOLLOWLOCATION, true);
无论如何,您不应该使用新的 URI,因为 HTTP 状态码 302 只是一个临时重定向。
【讨论】:
【参考方案7】:这是一种获取 curl http 请求返回的所有标头的方法,以及每个标头的状态代码和标头行数组。
$url = 'http://google.com';
$opts = array(CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => true,
CURLOPT_FOLLOWLOCATION => true);
$ch = curl_init();
curl_setopt_array($ch, $opts);
$return = curl_exec($ch);
curl_close($ch);
$headers = http_response_headers($return);
foreach ($headers as $header)
$str = http_response_code($header);
$hdr_arr = http_response_header_lines($header);
if (isset($hdr_arr['Location']))
$str .= ' - Location: ' . $hdr_arr['Location'];
echo $str . '<br />';
function http_response_headers($ret_str)
$hdrs = array();
$arr = explode("\r\n\r\n", $ret_str);
foreach ($arr as $each)
if (substr($each, 0, 4) == 'HTTP')
$hdrs[] = $each;
return $hdrs;
function http_response_header_lines($hdr_str)
$lines = explode("\n", $hdr_str);
$hdr_arr['status_line'] = trim(array_shift($lines));
foreach ($lines as $line)
list($key, $val) = explode(':', $line, 2);
$hdr_arr[trim($key)] = trim($val);
return $hdr_arr;
function http_response_code($str)
return substr(trim(strstr($str, ' ')), 0, 3);
【讨论】:
【参考方案8】:使用curl_getinfo($ch)
,第一个元素(url
)表示有效网址。
【讨论】:
以上是关于如何使用 cURL 获取目标 URL?的主要内容,如果未能解决你的问题,请参考以下文章
如何在curl方式下url请求域名使用指定ip地址来访问某个服务器