问题前言
PHP怎么获得HTTP 301 302重定向跳转后的真实地址?
短链接或是需要验证权限的链接,该怎么抓取跳转后的真实url?
给大家写了几种常用到的场景,并详细注释了代码,看看有没有你需要的
解决方案
1. curl函数
/** * 获取url重定向跳转后的真实地址(支持抓取需要登录验证权限的url) * @param str $url 请求的URL * @param str $num 0:关闭(抓取重定向后的链接,直到HTTP状态码为200) | 数字:(最多允许的HTTP重定向的数量) * @param str $cookie 0:关闭 | 路径:(存放cookie文件的绝对路径) * @return 重定向后的真实url **/ function check_url($url,$num=0,$cookie=0){ $httpcode = 0; $ch = curl_init(); // 初始化一个cURL对象 curl_setopt($ch ,CURLOPT_URL, $url); // 设置你需要抓取的URL curl_setopt($ch ,CURLOPT_SSL_VERIFYPEER, false);// false:禁止cURL验证对等证书 curl_setopt($ch ,CURLOPT_SSL_VERIFYHOST, false);// false:禁止检查证书 curl_setopt($ch ,CURLOPT_FOLLOWLOCATION, 1); // 获取转向后的内容 if($num){ curl_setopt($ch ,CURLOPT_MAXREDIRS, $num); // 设置最多的HTTP重定向的数量 } curl_setopt($ch ,CURLOPT_RETURNTRANSFER, 1); // 抓取结果直接返回到字符串中(0:则直接输出内容到页面) curl_setopt($ch ,CURLOPT_HEADER, true); // 允许输出响应头信息(true:是"会自动输出到页面"/false:否) curl_setopt($ch ,CURLOPT_NOBODY, true); // 只抓取头信息,不抓取页面内容 curl_setopt($ch ,CURLOPT_CONNECTTIMEOUT, 3); // 建立服务器连接所允许的最长时间(以秒为单位) curl_setopt($ch ,CURLOPT_TIMEOUT, 30); // 限制单个cURL扩展功能调用执行的最大时间量 防止死循环(秒) if($cookie){ curl_setopt($ch ,CURLOPT_COOKIEFILE, $cookie); // 读取cookie文件:在当前的会话中读取这个文件里的cookie去访问 curl_setopt($ch ,CURLOPT_COOKIEJAR, $cookie); // 写入cookie文件:会话结束时,把新获得的cookie信息保存到文件 } curl_exec($ch); // 运行cURL请求网页 $turl=curl_getinfo($ch ,CURLINFO_EFFECTIVE_URL);// 上次重定向的有效网址 curl_close($ch); // 关闭cURL资源,并且释放系统资源 return $turl; }
2. get_headers函数
/** * 获取多次跳转后真实的url地址 * @param str $url 查询 * @return 重定向后的真实url **/ function getrealurl($url){ $header = @get_headers($url,1);// 默认第二个参数0,可选1,返回关联数组 if(!$header){ exit('无法打开此网站'.$url); } //var_dump($header); if (strpos($header[0],'301') || strpos($header[0],'302')) { if(is_array($header['Location'])) { return $header['Location'][count($header['Location'])-1]; }else{ return $header['Location']; } }else { return $url; } }
使用提示
仅适用于抓取 Location 类的跳转301/302,如果是使用js跳转的中转页面则无法抓取,这种情况可以使用curl抓取网页后正则提取
请根据自己实际情况做相应修改
如有什么BUG或者疑问欢迎各路大神补充&指正