PHP - Parse_url只获取页面

时间:2012-08-11 10:21:59

标签: php parsing

我正在开发一个小型的webcrawler作为一个侧面项目,基本上让它收集页面上的所有href,然后解析那些,我的问题是。

我怎样才能获得实际的页面结果?目前我正在使用以下

foreach($page->getElementsByTagName('a') as $link) 
{
    $compare_url = parse_url($link->getAttribute('href'));
    if (@$compare_url['host'] == "") 
    { 
        $links[] = 'http://'.@$base_url['host'].'/'.$link->getAttribute('href');
    }
    elseif ( @$base_url['host'] == @$compare_url['host'] ) 
    {
            $links[] = $link->getAttribute('href');
    }   

 }

正如您所看到的,这将带来jpegs,exe文件等。我只需要拾取网页,如.php,.html,.asp等。

我不确定是否有某些功能可以解决这个问题,或者是否需要从某种主列表中使用正则表达式?

由于

3 个答案:

答案 0 :(得分:1)

由于URL字符串本身不以任何方式与其后面的资源相关联,因此您必须向Web服务器询问它们。为此,有一个名为HEAD的HTTP方法,因此您不必下载所有内容。

你可以在php中用curl实现这个:

function is_html($url) {
    function curl_head($url) {
        $curl = curl_init($url);
        curl_setopt($curl, CURLOPT_NOBODY, true);
        curl_setopt($curl, CURLOPT_HEADER, true);
        curl_setopt($curl, CURLOPT_MAXREDIRS, 5);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true );
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HTTP_VERSION , CURL_HTTP_VERSION_1_1);
        $content = curl_exec($curl);
        curl_close($curl);

        // redirected heads just pile up one after another
        $parts = explode("\r\n\r\n", trim($content));

        // return only the last one
        return end($parts);
    }
    $header = curl_head('http://github.com');
    // look for the content-type part of the header response
    return preg_match('/content-type\s*:\s*text\/html/i', $header);
}

var_dump(is_html('http://github.com'));

此版本仅接受text/html响应,不会检查响应是否为404或其他错误(但重定向最多为5次跳转)。您可以调整regexp或在curl响应中添加一些错误处理,或者通过匹配标题字符串的第一行。

注意: Web服务器将在这些URL后面运行脚本以便为您提供响应。注意不要使用探测过载主机,或者抓取“删除”或“取消订阅”类型的链接。

答案 1 :(得分:0)

检查页面是否有效(html,php ...扩展名使用此功能:

function check($url){
$extensions=array("php","html"); //Add extensions here
foreach($extensions as $ext){
if(substr($url,-(strlen($ext)+1))==".".$ext){
return 1;
}
}
return 0;
}
foreach($page->getElementsByTagName('a') as $link) {
    $compare_url = parse_url($link->getAttribute('href'));
    if (@$compare_url['host'] == "") { if(check($link->getAttribute('href'))){ $links[] = 'http://'.@$base_url['host'].'/'.$link->getAttribute('href');} }
    elseif ( @$base_url['host'] == @$compare_url['host'] ) {
            if(check($link->getAttribute('href'))){ $links[] = $link->getAttribute('href'); }
}   

答案 2 :(得分:0)

考虑使用preg_match检查链接的类型(应用程序,图片,html文件),并考虑结果决定该怎么做。

另一个选项(简单)是使用explode并找到.之后的最后一个网址字符串(扩展名) 例如:

//If the URL will has any one of the following extensions , ignore them.
$forbid_ext = array('jpg','gif','exe');

foreach($page->getElementsByTagName('a') as $link) {
    $compare_url = parse_url($link->getAttribute('href'));
    if (@$compare_url['host'] == "")
    { 
           if(check_link_type($link->getAttribute('href')))
           $links[] = 'http://'.@$base_url['host'].'/'.$link->getAttribute('href');
    }
    elseif ( @$base_url['host'] == @$compare_url['host'] )
    {
           if(check_link_type($link->getAttribute('href')))
            $links[] = $link->getAttribute('href');
    }   

    }

function check_link_type($url)
{
   global $forbid_ext;

   $ext = end(explode("." , $url));
   if(in_array($ext , $forbid_ext))
     return false;
   return true;
}

更新(而不是检查'禁止'扩展程序,让我们寻找好的扩展程序)

$good_ext = array('html','php','asp');
function check_link_type($url)
{
   global $good_ext;

   $ext = end(explode("." , $url));
   if($ext == "" || !in_array($ext , $good_ext))
     return true;
   return false;
}