使用PHP获取缩短URL(如bit.ly)的最终URL

3
[底部更新]
大家好。 从短链接开始:
想象一下,你有一个包含 5 个短链接(例如 http://bit.ly)的 PHP 数组,就像这样:
$shortUrlArray = array("http://bit.ly/123",
"http://bit.ly/123",
"http://bit.ly/123",
"http://bit.ly/123",
"http://bit.ly/123");

以最终的重定向链接结尾:
如何使用php获取这些短链接的最终url?像这样:

http://www.example.com/some-directory/some-page.html
http://www.example.com/some-directory/some-page.html
http://www.example.com/some-directory/some-page.html
http://www.example.com/some-directory/some-page.html
http://www.example.com/some-directory/some-page.html

我有一种方法(在网上找到的)可以正常使用单个url,但是循环多个url时只能使用数组中的最后一个url。供您参考,该方法如下:

function get_web_page( $url ) 
{ 
    $options = array( 
        CURLOPT_RETURNTRANSFER => true,     // return web page 
        CURLOPT_HEADER         => true,    // return headers 
        CURLOPT_FOLLOWLOCATION => true,     // follow redirects 
        CURLOPT_ENCODING       => "",       // handle all encodings 
        CURLOPT_USERAGENT      => "spider", // who am i 
        CURLOPT_AUTOREFERER    => true,     // set referer on redirect 
        CURLOPT_CONNECTTIMEOUT => 120,      // timeout on connect 
        CURLOPT_TIMEOUT        => 120,      // timeout on response 
        CURLOPT_MAXREDIRS      => 10,       // stop after 10 redirects 
    ); 

    $ch      = curl_init( $url ); 
    curl_setopt_array( $ch, $options ); 
    $content = curl_exec( $ch ); 
    $err     = curl_errno( $ch ); 
    $errmsg  = curl_error( $ch ); 
    $header  = curl_getinfo( $ch ); 
    curl_close( $ch ); 

    //$header['errno']   = $err; 
    //$header['errmsg']  = $errmsg; 
    //$header['content'] = $content; 
    print($header[0]); 
    return $header; 
}  


//Using the above method in a for loop

$finalURLs = array();

$lineCount = count($shortUrlArray);

for($i = 0; $i <= $lineCount; $i++){

    $singleShortURL = $shortUrlArray[$i];

    $myUrlInfo = get_web_page( $singleShortURL ); 

    $rawURL = $myUrlInfo["url"];

    array_push($finalURLs, $rawURL);

}

接近目标,但还不够
这种方法可以工作,但只能用于单个URL。我想要在for循环中使用它,但不能。当在for循环中使用上述示例时,前四个元素保持不变,只有最后一个元素会转换为其最终URL。无论数组是5个元素还是500个元素长,都会发生这种情况。

寻求的解决方案:
请给我一个提示,如何修改此方法以便在与URL集合一起使用时在for循环内部使用(而不仅仅是一个)。

-或-

如果您知道更适合此任务的代码,请在答案中包含它。

提前致谢。

更新:
经过进一步探究,我发现问题并不在上述方法中(毕竟,在for循环中似乎可以很好地工作),但可能与编码有关。当我硬编码一个短网址数组时,循环正常工作。但是当我使用GET或POST从HTML表单中传入一组用换行符分隔的网址块时,就会出现上述问题。当我提交表单时,URL是否被改成了不兼容该方法的格式???

新更新:
你们,我发现我的问题与上述方法无关。我的问题是,我的短网址的URL编码将我认为只是换行字符(分隔网址)转换为此:%0D%0A这是回车或换行符...所有短网址都除了集合中的最后一个URL以外,都在尾部附加了一个“幽灵”字符,因此对于那些仅有的最终URL是不可能检索的。我确定了幽灵字符,更正了我的php explode,现在一切都很好。抱歉和谢谢。

3个回答

2

我觉得你已经接近答案了。尝试以下方法:

$shortUrlArray = array("http://yhoo.it/2deaFR",
    "http://bit.ly/900913",
    "http://bit.ly/4m1AUx");

    $finalURLs = array();

    $lineCount = count($shortUrlArray);

    for($i = 0; $i < $lineCount; $i++){
            $singleShortURL = $shortUrlArray[$i];
            $myUrlInfo = get_web_page( $singleShortURL );
            $rawURL = $myUrlInfo["url"];
             printf($rawURL."\n");
            array_push($finalURLs, $rawURL);
    }

感谢您的回答。很抱歉,因为当URL数组硬编码到PHP脚本中时,您的方法和我的方法似乎都可以正常工作。但是,当我使用HTML表单(GET / POST)传递一系列短网址并通过其换行符拆分它们以创建数组时,问题似乎出现了...这是编码的问题吗? - m0rtimer

2
这可能会有所帮助:如何将字符串按换行符拆分成数组? 假设您正在POST中返回URL,您可能会这样做:
$final_urls = array();

$short_urls = explode( chr(10), $_POST['short_urls'] ); //You can replace chr(10) with "\n" or "\r\n", depending on how you get your urls. And of course, change $_POST['short_urls'] to the source of your string.

foreach ( $short_urls as $short ) {
    $final_urls[] = get_web_page( $short );
}

我使用var_dump($final_urls);和您的bit.ly网址,得到以下输出:

http://codepad.org/8YhqlCo1

这是我的源代码:$_POST['short_urls'] = "http://bit.ly/123\nhttp://bit.ly/123\nhttp://bit.ly/123\nhttp://bit.ly/123"; 当我使用您的函数时,我也遇到了一个错误:Notice: Undefined offset: 0 in /var/www/test.php on line 27。第27行:print($header[0]); 我不确定您想要什么...
如果有帮助的话,这是我的test.phphttp://codepad.org/zI2wAOWL

嗨,Mike。谢谢你的帮助。在看到你的答案之前,我已经找到了问题所在,即所有 URL 的末尾实际上都是回车符而不是换行符,但是集合中最后一个 URL 没有被我的 explode("\n", $urlBlock) 代码捕捉到。解决了这个问题,现在它可以工作了。 - m0rtimer
没问题,Eric。我很高兴你解决了这个问题。你可以做的一件事是在爆炸换行符之前用空格(或换行符,如果没有出现)替换回车符。 - Micheal

0

我实现了从纯文本文件中获取每一行的缩短 URL,以及相应的重定向 URL:

<?php
// input: textfile with one bitly shortened url per line
$plain_urls = file_get_contents('in.txt');
$bitly_urls = explode("\r\n", $plain_urls);

// output: where should we write
$w_out = fopen("out.csv", "a+") or die("Unable to open file!");

foreach($bitly_urls as $bitly_url) {
  $c = curl_init($bitly_url);
  curl_setopt($c, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36');
  curl_setopt($c, CURLOPT_FOLLOWLOCATION, 0);
  curl_setopt($c, CURLOPT_HEADER, 1);
  curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 20);
  // curl_setopt($c, CURLOPT_PROXY, 'localhost:9150');
  // curl_setopt($c, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
  $r = curl_exec($c);

  // get the redirect url:
  $redirect_url = curl_getinfo($c)['redirect_url'];

  // write output as csv
  $out = '"'.$bitly_url.'";"'.$redirect_url.'"'."\n";
  fwrite($w_out, $out);
}
fclose($w_out);

玩得开心,尽情享受! pw


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接