【问题标题】:cURL get url from redirectcURL 从重定向中获取 url
【发布时间】:2013-06-06 06:11:44
【问题描述】:

我目前正在使用 cURL 尝试从网站抓取工具的重定向中获取 URL。我只需要网站上的网址。在过去的几天里,我研究了 stackoverflow 和其他网站,但没有成功。我目前使用的代码来自这个网站:

  $url = "http://www.someredirect.com";
  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1');         
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HEADER, true);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
  curl_setopt($ch, CURLOPT_NOBODY, true);
  $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';

任何帮助将不胜感激!

【问题讨论】:

  • preg_match_all('/^Location:(.*)$/mi', $response, $matches);,例如,您是否要匹配 header('Location:http://google.com');? ://
  • 是的。尝试从标头解析位置,但标头中未返回位置标记。
  • 在这种情况下,您的代码对我来说可以正常工作。

标签: php url redirect curl


【解决方案1】:

在您的特定情况下,服务器正在检查某些用户代理字符串。

当服务器检查用户代理字符串时,它只会在服务器看到“有效”(根据服务器)用户代理时返回 302 重定向状态代码。任何“无效”的用户代理都不会收到302 重定向状态代码响应或Location: 标头。

在您的特定情况下,当服务器收到来自“无效”用户代理的请求时,它会以 200 OK 状态代码进行响应,而响应正文中没有文本。

注意:在下面的代码中,提供的实际 URL 已替换为示例。)

假设http://www.example.com 的服务器检查用户代理字符串并且http://www.example.com/product/123/ 重定向到http://www.example.org/abc

在 PHP 中,您的解决方案是:

<?php

$url = 'http://www.example.com/product/123/';

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; Linux x86_64; rv:21.0) Gecko/20100101 Firefox/21.0"); // Necessary. The server checks for a valid User-Agent.
curl_exec($ch);

$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';

而且,这个脚本的输出是:http://www.example.org/abc

【讨论】:

  • 是的,我注意到了,应该说点什么。如果它不是技术重定向,但仍指向不同的站点,我将如何获取我想要的 url?
  • 在命令行上,您可以使用curl 验证您的重定向。例如,curl -IL http://microsoft.com 将首先给你状态码 301,然后是 200。当我输入你给我的 url 时,我在第一个 URL 上得到 200 OK 状态码。
  • @Josh 取决于重定向的完成方式。如果重定向是在 HTML 或 JavaScript 中完成的,此链接应该会有所帮助:stackoverflow.com/questions/12633369/…
  • 更新了解决方案,使其适用于这个特定的服务器。此外,我用示例替换了@Josh 提供的实际 URL。
【解决方案2】:

尝试使用此代码:

function curl_last_url(/*resource*/ $ch, /*int*/ &$maxredirect = null) { 
$mr = $maxredirect === null ? 5 : intval($maxredirect); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); 
    if ($mr > 0) { 
        echo $mr;
        echo $newurl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); 

        $rch = curl_copy_handle($ch); 
        curl_setopt($rch, CURLOPT_HEADER, true); 
        curl_setopt($rch, CURLOPT_NOBODY, true); 
        curl_setopt($rch, CURLOPT_FORBID_REUSE, false); 
        curl_setopt($rch, CURLOPT_RETURNTRANSFER, true); 
        do { 
            curl_setopt($rch, CURLOPT_URL, $newurl); 
            $header = curl_exec($rch); 
            if (curl_errno($rch)) { 
                $code = 0; 
            } else { 
                $code = curl_getinfo($rch, CURLINFO_HTTP_CODE); 
                echo $code;
                if ($code == 301 || $code == 302) { 
                    preg_match('/Location:(.*?)\n/', $header, $matches); 
                    $newurl = trim(array_pop($matches)); 
                } else { 
                    $code = 0; 
                } 
            } 
        } while ($code && --$mr); 
        curl_close($rch); 
        if (!$mr) { 
            if ($maxredirect === null) { 
                trigger_error('Too many redirects. When following redirects, libcurl hit the maximum amount.', E_USER_WARNING); 
            } else { 
                $maxredirect = 0; 
            } 
            return false; 
        } 
        curl_setopt($ch, CURLOPT_URL, $newurl); 
    } 
return $newurl; 

}

【讨论】:

    猜你喜欢
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-24
    • 2011-05-03
    • 2021-03-28
    相关资源
    最近更新 更多