2

私は現在、サイドプロジェクトとして小さなウェブクローラーに取り組んでおり、基本的にはページ上のすべての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');
    }   

 }

ご覧のとおり、これによりjpeg、exeファイルなどが取り込まれます。.php、.html、.aspなどのWebページを取得するだけで済みます。

これを実行できる関数があるかどうか、またはある種のマスターリストから正規表現にする必要があるかどうかはわかりませんか?

ありがとう

4

3 に答える 3

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ジャンプのリダイレクトに従います)。正規表現を微調整するか、curl応答から、またはヘッダー文字列の最初の行と照合することにより、エラー処理を追加できます。

注: Webサーバーは、これらのURLの背後でスクリプトを実行して、応答を提供します。プロービング、または「削除」または「購読解除」タイプのリンクを取得してホストを過負荷にしないように注意してください。

于 2012-08-11T12:04:59.957 に答える
0

preg_matchリンクのタイプ (アプリケーション、画像、html ファイル) を確認するために使用することを検討し、結果を考慮して何をすべきかを決定します。

もう1つのオプション(そして簡単な)はexplode、(拡張子)の後に来るURLの最後の文字列を使用して見つけることです.。たとえば:

//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;
}
于 2012-08-11T10:40:41.673 に答える
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'); }
}   
于 2012-08-11T10:39:17.203 に答える