【问题标题】:Finding URL redirects with HTTP headers and curl?使用 HTTP 标头和 curl 查找 URL 重定向?
【发布时间】:2012-01-21 23:17:59
【问题描述】:

我正在尝试编写重定向检查器,以检查 URL 是否对搜索引擎友好。它必须检查一个 URL 是否被重定向,如果它被重定向,它必须判断它是否对 SEO 友好(301 状态代码)或不(302/304)。

我发现了类似的东西:http://www.webconfs.com/redirect-check.php

它还应该能够跟踪多个重定向(例如,从 A 到 B 到 C)并告诉我 A 重定向到 C。

这是我到目前为止得到的,但它不能正常工作(例如:在输入 www.example.com 时,它没有找到到 www.example.com/page1 的重定向)

<?php
// You can edit the messages of the respective code over here
$httpcode  = array();
$httpcode["200"] = "Ok";
$httpcode["201"] = "Created";
$httpcode["302"] = "Found";
$httpcode["301"] = "Moved Permanently";
$httpcode["304"] = "Not Modified";
$httpcode["400"] = "Bad Request";


if(count($_POST)>0)
{
    $url = $_POST["url"];
    $curlurl = "http://".$url."/";
    $ch = curl_init();
    // Set URL to download
    curl_setopt($ch, CURLOPT_URL, $curlurl);

    // User agent
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER["HTTP_USER_AGENT"]);
    // Include header in result? (0 = yes, 1 = no)
    curl_setopt($ch, CURLOPT_HEADER, 0);

    // Should cURL return or print out the data? (true = return, false = print)
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    // Timeout in seconds
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);

    // Download the given URL, and return output
    $output = curl_exec($ch);

    $curlinfo = curl_getinfo($ch);

    if(($curlinfo["http_code"]=="301") || ($curlinfo["http_code"]=="302"))
    {
        $ch = curl_init();
        // Set URL to download
        curl_setopt($ch, CURLOPT_URL, $curlurl);

        // User agent
        curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER["HTTP_USER_AGENT"]);
        // Include header in result? (0 = yes, 1 = no)
        curl_setopt($ch, CURLOPT_HEADER, 0);

        // Should cURL return or print out the data? (true = return, false = print)
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        // Timeout in seconds
        curl_setopt($ch, CURLOPT_TIMEOUT, 15);


        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        // Download the given URL, and return output
        $output = curl_exec($ch);

        $curlinfo = curl_getinfo($ch);
        echo $url." is redirected to ".$curlinfo["url"];
    }
    else
    {
        echo $url." is not getting redirected";
    }

    // Close the cURL resource, and free system resources
    curl_close($ch);
}
?>
<form action="" method="post">
http://<input type="text" name="url" size="30" />/ <b>e.g. www.google.com</b><br/>
<input type="submit" value="Submit" />
</form>

【问题讨论】:

标签: php redirect curl http-headers


【解决方案1】:

如果你想记录每个重定向,你必须自己实现它并关闭自动“位置跟踪”:

function curl_trace_redirects($url, $timeout = 15) {

    $result = array();
    $ch = curl_init();

    $trace = true;
    $currentUrl = $url;

    $urlHist = array();
    while($trace && $timeout > 0 && !isset($urlHist[$currentUrl])) {
        $urlHist[$currentUrl] = true;

        curl_setopt($ch, CURLOPT_URL, $currentUrl);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_NOBODY, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);

        $output = curl_exec($ch);

        if($output === false) {
            $traceItem = array(
                'errorno' => curl_errno($ch),
                'error' => curl_error($ch),
            );

            $trace = false;
        } else {
            $curlinfo = curl_getinfo($ch);

            if(isset($curlinfo['total_time'])) {
                $timeout -= $curlinfo['total_time'];
            }

            if(!isset($curlinfo['redirect_url'])) {
                $curlinfo['redirect_url'] = get_redirect_url($output);
            }

            if(!empty($curlinfo['redirect_url'])) {
                $currentUrl = $curlinfo['redirect_url'];
            } else {
                $trace = false;
            }

            $traceItem = $curlinfo;
        }

        $result[] = $traceItem;
    }

    if($timeout < 0) {
        $result[] = array('timeout' => $timeout);
    }

    curl_close($ch);

    return $result;
}

// apparently 'redirect_url' is not available on all curl-versions
// so we fetch the location header ourselves
function get_redirect_url($header) {
    if(preg_match('/^Location:\s+(.*)$/mi', $header, $m)) {
        return trim($m[1]);
    }

    return "";
}

然后你就这样使用它:

$res = curl_trace_redirects("http://www.example.com");
foreach($res as $item) {
    if(isset($item['timeout'])) {
        echo "Timeout reached!\n";
    } else if(isset($item['error'])) {
        echo "error: ", $item['error'], "\n";
    } else {
        echo $item['url'];
        if(!empty($item['redirect_url'])) {
            // redirection
            echo " -> (", $item['http_code'], ")";
        }

        echo "\n";
    }
}

我的代码可能没有经过深思熟虑,但我想这是一个好的开始。

编辑

这是一些示例输出:

http://midas/~stefan/test/redirect/fritzli.html -> (302)
http://midas/~stefan/test/redirect/hansli.html -> (301)
http://midas/~stefan/test/redirect/heiri.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 2015-11-09
    相关资源
    最近更新 更多