Php 如何仅加载html(并跳过媒体文件)

Php 如何仅加载html(并跳过媒体文件),php,http,curl,web-crawler,Php,Http,Curl,Web Crawler,我正在优化我的简单网络爬虫(目前使用PHP/curl\u multi) 目标是在智能的同时抓取整个网站,并跳过非html内容。我尝试使用nobody,只发送HEAD请求,但这似乎并不适用于所有网站(有些服务器不支持HEAD),导致exec暂停很长时间(有时比加载页面本身长得多) 有没有其他方法可以在不下载整个内容的情况下获取页面类型,或者在文件不是html的情况下强制CURL放弃下载 (编写自己的http客户端不是一个选项,因为我打算稍后将CURL函数用作cookie和ssl)。您看过了吗 您可

我正在优化我的简单网络爬虫(目前使用PHP/curl\u multi)

目标是在智能的同时抓取整个网站,并跳过非html内容。我尝试使用nobody,只发送HEAD请求,但这似乎并不适用于所有网站(有些服务器不支持HEAD),导致exec暂停很长时间(有时比加载页面本身长得多)

有没有其他方法可以在不下载整个内容的情况下获取页面类型,或者在文件不是html的情况下强制CURL放弃下载

(编写自己的http客户端不是一个选项,因为我打算稍后将CURL函数用作cookie和ssl)。

您看过了吗

您可以打开远程页面的套接字,只读取必要的内容。一旦识别出
内容类型
标题,就可以关闭连接

<?php
$type = 'Unknown';
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: www.example.com\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);

    $in = '';
    while (!feof($fp)) {
        $in .= fgets($fp, 128);
        if ( preg_match( '/Content-Type: (.+)\n/i', $in, &$matches ) ) {
            $type = $matches[1];
            break;
        }
    }
    fclose($fp);
}
echo $type;
?>

我还没有试过,但我看到了
CURLOPT\u PROGRESSFUNCTION
。我敢打赌,如果您对正在下载的内容不感兴趣,您可以逐步阅读响应以查找
内容类型
标题,并可能()句柄

CURLOPT_PROGRESSFUNCTION     The name of a callback function
where the callback function takes three parameters. The first is the
cURL resource, the second is a file-descriptor resource, and the 
third is length. Return the string containing the data.
这对我很有效:


正确的方法是使用

curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'curlHeaderCallback');
回调将接受两个参数——第一个卷曲句柄,第二个卷曲头。每次新标头到达时都会调用它

$acceptable=array('application/xhtml+xml',
'application/xml', 'text/plain',
'text/xml', 'text/html');

function curlHeaderCallback($resURL, $strHeader) { 
    global $acceptable;
    if (stripos($strHeader,'content-type')===0) {
        $type=strtolower(trim(array_shift(explode(';',array_pop(explode(':',$strHeader))))));
        if (!in_array($type,$acceptable))
            return 0;
    }
    return strlen($strHeader); 

}

正如我所说,编写自己的http客户机目前太多了。如果我没有正确的cookies,很多页面甚至不会打开,没有提到ssl和其他东西,比如重定向,等等。在这段代码中,在检查页面类型之前,您实际上下载了整个页面。几乎完美。这有两个主要问题:首先,您无法从回调函数中curl_close(),它只给出警告消息。第二,无法判断哪个curl句柄调用了函数(在使用curl\u multi时很重要)。但是你的暗示让我找到了正确的答案,谢谢。你应该接受你自己的答案,因为它是最正确的。