161

私はいくつかの基本的なスクレイピングを独学していますが、コードに入力した URL が 404 を返すことがあり、残りのすべてのコードを台無しにしていることがわかりました。

そのため、URL が 404 を返すかどうかを確認するために、コードの先頭にテストが必要です。

これは非常に簡単な作業のように思えますが、Google からは何の回答も得られません。間違ったものを探しているのではないかと心配しています。

あるブログでは、これを使用することをお勧めします。

$valid = @fsockopen($url, 80, $errno, $errstr, 30);

次に、$valid が空かどうかをテストします。

しかし、問題を引き起こしている URL にはリダイレクトがあると思うので、$valid はすべての値に対して空になっています。または、おそらく私は何か他のことを間違っています。

「ヘッドリクエスト」も調べましたが、実際に遊んだり試したりできる実際のコード例はまだ見つかりません。

提案?そして、これはカールについて何ですか?

4

15 に答える 15

295

PHP のcurlbindingscurl_getinfoを使用している場合は、次のように使用してエラー コードを確認できます。

$handle = curl_init($url);
curl_setopt($handle,  CURLOPT_RETURNTRANSFER, TRUE);

/* Get the HTML or whatever is linked in $url. */
$response = curl_exec($handle);

/* Check for 404 (file not found). */
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
    /* Handle 404 here. */
}

curl_close($handle);

/* Handle $response here. */
于 2009-01-03T00:56:06.710 に答える
110

php5 を実行している場合は、次を使用できます。

$url = 'http://www.example.com';
print_r(get_headers($url, 1));

あるいは、php4 を使用して、ユーザーが次のように貢献しました。

/**
This is a modified version of code from "stuart at sixletterwords dot com", at 14-Sep-2005 04:52. This version tries to emulate get_headers() function at PHP4. I think it works fairly well, and is simple. It is not the best emulation available, but it works.

Features:
- supports (and requires) full URLs.
- supports changing of default port in URL.
- stops downloading from socket as soon as end-of-headers is detected.

Limitations:
- only gets the root URL (see line with "GET / HTTP/1.1").
- don't support HTTPS (nor the default HTTPS port).
*/

if(!function_exists('get_headers'))
{
    function get_headers($url,$format=0)
    {
        $url=parse_url($url);
        $end = "\r\n\r\n";
        $fp = fsockopen($url['host'], (empty($url['port'])?80:$url['port']), $errno, $errstr, 30);
        if ($fp)
        {
            $out  = "GET / HTTP/1.1\r\n";
            $out .= "Host: ".$url['host']."\r\n";
            $out .= "Connection: Close\r\n\r\n";
            $var  = '';
            fwrite($fp, $out);
            while (!feof($fp))
            {
                $var.=fgets($fp, 1280);
                if(strpos($var,$end))
                    break;
            }
            fclose($fp);

            $var=preg_replace("/\r\n\r\n.*\$/",'',$var);
            $var=explode("\r\n",$var);
            if($format)
            {
                foreach($var as $i)
                {
                    if(preg_match('/^([a-zA-Z -]+): +(.*)$/',$i,$parts))
                        $v[$parts[1]]=$parts[2];
                }
                return $v;
            }
            else
                return $var;
        }
    }
}

どちらも次のような結果になります。

Array
(
    [0] => HTTP/1.1 200 OK
    [Date] => Sat, 29 May 2004 12:28:14 GMT
    [Server] => Apache/1.3.27 (Unix)  (Red-Hat/Linux)
    [Last-Modified] => Wed, 08 Jan 2003 23:11:55 GMT
    [ETag] => "3f80f-1b6-3e1cb03b"
    [Accept-Ranges] => bytes
    [Content-Length] => 438
    [Connection] => close
    [Content-Type] => text/html
)

したがって、ヘッダーの応答が OK であることを確認するだけで済みます。

$headers = get_headers($url, 1);
if ($headers[0] == 'HTTP/1.1 200 OK') {
//valid 
}

if ($headers[0] == 'HTTP/1.1 301 Moved Permanently') {
//moved or redirect page
}

W3C コードと定義

于 2009-01-03T01:01:18.383 に答える
39

strager のコードを使用すると、CURLINFO_HTTP_CODE で他のコードを確認することもできます。一部の Web サイトは 404 を報告せず、単にカスタム 404 ページにリダイレクトして 302 (リダイレクト) などを返します。これを使用して、サーバー上に実際のファイル (例: robots.txt) が存在するかどうかを確認しました。明らかにこの種のファイルは、存在する場合はリダイレクトを引き起こしませんが、存在しない場合は 404 ページにリダイレクトされます。前に述べたように、404 コードがない可能性があります。

function is_404($url) {
    $handle = curl_init($url);
    curl_setopt($handle,  CURLOPT_RETURNTRANSFER, TRUE);

    /* Get the HTML or whatever is linked in $url. */
    $response = curl_exec($handle);

    /* Check for 404 (file not found). */
    $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
    curl_close($handle);

    /* If the document has loaded successfully without any redirection or error */
    if ($httpCode >= 200 && $httpCode < 300) {
        return false;
    } else {
        return true;
    }
}
于 2011-01-03T13:31:35.610 に答える
24

strager が示唆するように、cURL の使用を検討してください。curl_setoptで CURLOPT_NOBODY を設定して、ページ全体のダウンロードをスキップすることもできます (ヘッダーだけが必要です)。

于 2009-01-03T00:59:16.750 に答える
16

最も簡単な解決策と、php5 で一度に試すことができる解決策を探している場合は、

file_get_contents('www.yoursite.com');
//and check by echoing
echo $http_response_header[0];
于 2011-05-12T14:43:14.843 に答える
8

ここでこの答えを見つけました:

if(($twitter_XML_raw=file_get_contents($timeline))==false){
    // Retrieve HTTP status code
    list($version,$status_code,$msg) = explode(' ',$http_response_header[0], 3);

    // Check the HTTP Status code
    switch($status_code) {
        case 200:
                $error_status="200: Success";
                break;
        case 401:
                $error_status="401: Login failure.  Try logging out and back in.  Password are ONLY used when posting.";
                break;
        case 400:
                $error_status="400: Invalid request.  You may have exceeded your rate limit.";
                break;
        case 404:
                $error_status="404: Not found.  This shouldn't happen.  Please let me know what happened using the feedback link above.";
                break;
        case 500:
                $error_status="500: Twitter servers replied with an error. Hopefully they'll be OK soon!";
                break;
        case 502:
                $error_status="502: Twitter servers may be down or being upgraded. Hopefully they'll be OK soon!";
                break;
        case 503:
                $error_status="503: Twitter service unavailable. Hopefully they'll be OK soon!";
                break;
        default:
                $error_status="Undocumented error: " . $status_code;
                break;
    }

基本的に、"file get contents" メソッドを使用して URL を取得します。これにより、http 応答ヘッダー変数にステータス コードが自動的に入力されます。

于 2009-01-03T00:55:07.583 に答える
4

この関数は、PHP 7 の URL のステータス コードを返します。

/**
 * @param string $url
 * @return int
 */
function getHttpResponseCode(string $url): int
{
    $headers = get_headers($url);
    return substr($headers[0], 9, 3);
}

例:

echo getHttpResponseCode('https://www.google.com');
//displays: 200
于 2020-04-14T10:21:20.533 に答える
2

広く受け入れられている答えへの追加のヒントとして:

提案されたソリューションのバリエーションを使用すると、php設定'max_execution_time'が原因でエラーが発生しました。だから私がしたことは次のとおりでした:

set_time_limit(120);
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_NOBODY, true);
$result = curl_exec($curl);
set_time_limit(ini_get('max_execution_time'));
curl_close($curl);

最初に制限時間をより高い秒数に設定し、最後にphp設定で定義された値に戻しました。

于 2011-08-14T14:01:43.047 に答える
2
<?php

$url= 'www.something.com';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, true);   
curl_setopt($ch, CURLOPT_NOBODY, true);    
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.4");
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT,10);
curl_setopt($ch, CURLOPT_ENCODING, "gzip");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$output = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);


echo $httpcode;
?>
于 2014-06-24T06:48:45.293 に答える
2

ここに短い解決策があります。

$handle = curl_init($uri);
curl_setopt($handle,  CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($handle,CURLOPT_HTTPHEADER,array ("Accept: application/rdf+xml"));
curl_setopt($handle, CURLOPT_NOBODY, true);
curl_exec($handle);
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
if($httpCode == 200||$httpCode == 303) 
{
    echo "you might get a reply";
}
curl_close($handle);

あなたの場合、application/rdf+xml使用するものに変更できます。

于 2013-08-26T01:38:34.047 に答える
1

このコードを使用して、リンクのステータスを確認することもできます。

<?php

function get_url_status($url, $timeout = 10) 
{
$ch = curl_init();
// set cURL options
$opts = array(CURLOPT_RETURNTRANSFER => true, // do not output to browser
            CURLOPT_URL => $url,            // set URL
            CURLOPT_NOBODY => true,         // do a HEAD request only
            CURLOPT_TIMEOUT => $timeout);   // set timeout
curl_setopt_array($ch, $opts);
curl_exec($ch); // do it!
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE); // find HTTP status
curl_close($ch); // close handle
echo $status; //or return $status;
    //example checking
    if ($status == '302') { echo 'HEY, redirection';}
}

get_url_status('http://yourpage.comm');
?>
于 2013-03-26T12:29:04.637 に答える
0

これは単なるコードの一部です。うまくいくことを願っています

            $ch = @curl_init();
            @curl_setopt($ch, CURLOPT_URL, 'http://example.com');
            @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, 1);
            @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
            @curl_setopt($ch, CURLOPT_TIMEOUT, 10);

            $response       = @curl_exec($ch);
            $errno          = @curl_errno($ch);
            $error          = @curl_error($ch);

                    $response = $response;
                    $info = @curl_getinfo($ch);
return $info['http_code'];
于 2009-01-03T01:01:01.847 に答える