本帖最后由 lovewangya 于 2009-11-19 22:14:49 编辑

解决方案 »

  1.   

    谢谢,以前好像php版块哪个朋友回复过,是可以的,但我忘记方法了,好像是一个变量或者函数什么的
      

  2.   

    这样做,curl就不会返回body了,但是实际上还是把包抓回来了,带宽已经占用了
    <?php
    $ch = curl_init();curl_setopt($ch, CURLOPT_URL, "http://www.baidu.com/");
    curl_setopt($ch, CURLOPT_HEADER, TRUE);
    curl_setopt($ch, CURLOPT_NOBODY, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);$hd = curl_exec($ch);
    curl_close($ch);print_r($hd);?> 
      

  3.   

    也不是所有的页面都有Content-Length这一个字段的,
    有些页面不发送这个东西,而是把长度放在了body里面。实际上,即使你自己写socket,也没有用,当你从server读取了100个字节的时候,
    你无法阻止server向你发送后来的N字节,程序中可以不去read,甚至立即关闭socket,
    但是那都没用,网卡已经收到了数据包,只不过不会被你的程序取走,而是被内核丢弃掉。TCP虽然有拥塞控制,你不读取的时候,数据不会源源不断的发送过来,
    但是,在达到“拥塞”之前,你没法阻止数据包过来。简单的说,开头的若干K字节,你是没法让它不到达你的主机的,
    除非你绕过内核,不使用内核的TCP协议实现。其实,那样做没有意义,不照单全收,后果就是无法使用keepalive特性,
    每次抓取相同站点的时候,都不得不重新建立socket和关闭socket,
    建立连接要3分节,关闭连接要4分节,而网络一般存在延时,数据包虽不多,开销却很大。
    传递10个不到10字节的数据包,要比传递一个100字节的包慢很多,就是这个道理
      

  4.   

    $headers = get_headers($url,1);
    echo $headers['Content-Type'];
      

  5.   


    呵呵,刚起来测试一下你的效果,同时也十分感谢:do_fork  的热心帮助。
      

  6.   

    公布测试结果
    curl要比get_headers快好多,什么原因我也不知道,呵呵
    631775
    页面执行时间: 2151.3 毫秒
    HTTP/1.1 200 OK Server: nginx/0.7.62 Date: Fri, 20 Nov 2009 05:11:29 GMT Content-Type: text/html Content-Length: 631775 Last-Modified: Fri, 20 Nov 2009 05:11:08 GMT Connection: keep-alive Expires: Fri, 20 Nov 2009 05:11:59 GMT Cache-Control: max-age=30 Accept-Ranges: bytes 页面执行时间: 369.8 毫秒
    源码:
    <?php
    include_once(dirname(__FILE__) . "/inc/config.php");
    $url = "http://blog.sina.com.cn/";
    $runtime = new runtime;
    $runtime->start();
    $headers = get_headers($url,1); 
    echo $headers['Content-Length'] . "<br>";
    $runtime->stop();
    echo "页面执行时间: ".$runtime->spent()." 毫秒<br>";$runtime->start();
    $ch = curl_init(); // 启动一个CURL会话
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_HEADER,1); //不示返回的Header区域内容
    curl_setopt($ch, CURLOPT_NOBODY, TRUE); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
    $hd = curl_exec($ch);
    curl_close($ch); 
    print_r($hd);
    $runtime->stop();
    echo "页面执行时间: ".$runtime->spent()." 毫秒<br>";
    ?>
      

  7.   

    class runtime

        var $StartTime = 0; 
        var $StopTime = 0; 
     
        function get_microtime() 
        { 
            list($usec, $sec) = explode(' ', microtime()); 
            return ((float)$usec + (float)$sec); 
        } 
     
        function start() 
        { 
            $this->StartTime = $this->get_microtime(); 
        } 
     
        function stop() 
        { 
            $this->StopTime = $this->get_microtime(); 
        } 
     
        function spent() 
        { 
            return round(($this->StopTime - $this->StartTime) * 1000, 1); 
        } 
    }
      

  8.   

    其实建立socket,发送http请求,在c源码层面应该都是调用同一个socket handler,只不过再度封装的形态各有所异,类似的还有fsockopen,fopen,file,file_get_contents...你要比较时间,得把返回头解析的时间也算进curl里去.我这边用你的代码刷新10几次,还是get_headers平均快一点呀..呵呵.
      

  9.   


    数据获取过来的。curl的头解析用一个正则就可以匹配了。总长度也不超过1000估计占用时间可以忽略不计吧?你那get_headers快?
      

  10.   

    刷了几次次,贴上来631869
    =============
    time : 46.3 ms
    ============
    time : 51.5 ms631869
    =============
    time : 38.4 ms
    ============
    time : 63.5 ms
    631869
    =============
    time : 31.9 ms
    ============
    time : 53.5 ms631871
    =============
    time : 31.6 ms
    ============
    time : 66.7 ms631871
    =============
    time : 54.2 ms
    ============
    time : 51.3 ms
      

  11.   

    如果目标支持,用HEAD代替GET
    如果我没记错的话HEAD除了不返回内容,其他与GET无异,所以对于只要http头的来说是最适合的
      

  12.   


    这么做没用,节省不了带宽,拿wireshark抓包看一下,还是把http header以外的都抓回来了GET / HTTP/1.0Host: www.baidu.comHTTP/1.1 200 OKDate: Fri, 20 Nov 2009 08:41:41 GMTServer: BWS/1.0Content-Length: 3520Content-Type: text/html;charset=gb2312Cache-Control: privateExpires: Fri, 20 Nov 2009 08:41:41 GMTSet-Cookie: BAIDUID=0FACC488933272ECFA2C0BFB27E496B2:FG=1; expires=Fri, 20-Nov-39 08:41:41 GMT; path=/; domain=.baidu.comP3P: CP=" OTI DSP COR IVA OUR IND COM "<html><head><meta http-equiv=Content-Type content="text/html;charset=gb2312"><title>..................      </title><style>body{margin:4px 0}p{margin:0;padding:0}img{border:0}td,p,#u{font-size:12px}#b,#u,#l td,a{font-family:arial}#kw{font:16px Verdana;height:1.78em;padding-top:2px}#b{height:30px;padding-top:4px}#b,#b a{color:#77c}#u{padding-right:10px;line-height:19px;text-align:right;margin:0 0 3px !important;margin:0 0 10px}#sb{height:2em;width:5.6em}#km{height:50px}#l{margin:0 0 5px 15px}#l td{padding-left:107px}p,table{width:650px;border:0}#l td,#sb,#km{font-size:14px}#l a,#l b{margin-right:1.14em}a{color:#00c}a:active{color:#f60}#hp{position:absolute;margin-left:6px}#lg{margin:-26px 0 -44px}#lk{width:auto;line-height:18px;vertical-align:top}form{position:relative;z-index:9}</style></head>
    <body><div id=u><a href=http://passport.baidu.com/?login&tpl=mn>....</a></div><center><img src=http://www.baidu.com/img/baidu_logo.gif width=270 height=129 usemap="#mp" id=lg><br><br><br><br><table cellpadding=0 cellspacing=0 id=l><tr><td><div id=m><a onclick=s(this) href=http://news.baidu.com>..&nbsp;..</a><b>..&nbsp;..</b><a onclick=s(this) href=http://tieba.baidu.com>..&nbsp;..</a><a onclick=s(this) href=http://zhidao.baidu.com>..&nbsp;..</a><a onclick=s(this) href=http://mp3.baidu.com>MP3</a><a onclick=s(this) href=http://image.baidu.com>..&nbsp;..</a><a onclick=s(this) href=http://video.baidu.com>..&nbsp;..</a></div></td></tr></table>
    <table cellpadding=0 cellspacing=0 style="margin-left:15px"><tr valign=top><td style="height:62px;padding-left:92px" nowrap><form name=f action=s><input type=text name=wd id=kw size=42 maxlength=100> <input type=submit value=........ id=sb><span id=hp><a href=/gaoji/preferences.html>....</a><br><a href=/gaoji/advanced.html>....</a></span></form></td></tr></table>
    <p id=km><a href=http://hi.baidu.com>....</a>&nbsp;&nbsp;<a href=http://www.hao123.com>hao123</a>&nbsp;|&nbsp;<a href=/more/>....<span style="font-family:....">>></span></a></p>
    <p style=height:60px><table cellpadding=0 cellspacing=0 id=lk><tr><td></td></tr></table></p>
    <p style=height:30px><a onClick="this.style.behavior='url(#default#homepage)';this.setHomePage('http://www.baidu.com')" href=http://utility.baidu.com/traf/click.php?id=215&url=http://www.baidu.com>..............</a></p><p style=height:14px><a href=http://e.baidu.com>............</a> | <a href=http://top.baidu.com>..........</a> | <a href=http://home.baidu.com>........</a> | <a href=http://ir.baidu.com>About Baidu</a></p><p id=b>&copy;2009 Baidu <a href=http://www.baidu.com/duty/>..............</a> <a href=http://www.miibeian.gov.cn target=_blank>..ICP..030173..</a> <img src=http://gimg.baidu.com/img/gs.gif></p><map name=mp><area shape=rect coords="43,22,227,91" href=http://hi.baidu.com/baidu/ target=_blank title="........ ........"></map></center></body>
    <script>var w=document.f.wd;function s(o){if(w.value.length>0){var h=o.href;var q=encodeURIComponent(w.value);if(h.indexOf("q=")!=-1){o.href=h.replace(new RegExp("q=[^&$]*"),"q="+q)}else{o.href+="?q="+q}}};(function(){if(new RegExp("q=([^&]+)").test(location.search)){w.value=decodeURIComponent(RegExp.$1)}})();if(navigator.cookieEnabled&&!/sug?=0/.test(document.cookie)){document.write('<script src=http://www.baidu.com/js/bdsug.js?v=1.1.0.3><\/script>')};if(window.attachEvent){window.attachEvent("onload",function(){w.focus();})}else{window.addEventListener('load',function(){w.focus()},true)};window.onunload=function(){};</script></html><!--0e94a8fd6438cdd2-->
      

  13.   


    如果服务器支持的话,head应该是可以的,百度是不支持的,其它站点可能支持。百度的前若干字节看
    $ telnet www.baidu.com 80
    Trying 119.75.216.30...
    Connected to www.a.shifen.com.
    Escape character is '^]'.
    HEAD / HTTP/1.0HTTP/1.1 200 OK
    Date: Fri, 20 Nov 2009 08:47:47 GMT
    Server: BWS/1.0
    Content-Length: 3520
    Content-Type: text/html;charset=gb2312
    Cache-Control: private
    Expires: Fri, 20 Nov 2009 08:47:47 GMT
    Set-Cookie: BAIDUID=9BE0AC8E2756000918DFD99CD3D7CCEC:FG=1; expires=Fri, 20-Nov-39 08:47:47 GMT; path=/; domain=.baidu.com
    P3P: CP=" OTI DSP COR IVA OUR IND COM "<html><head><meta http-equiv=Content-Type content="text/html;charset=gb2312"><title>°????£????aμ      </title><style>body{margin:4px 0}p{margin:0;padding:0}img{border:0}td,p,#u{font-size:12px}#b,#u,#l td,a{font-family:arial}#kw{font:16px Verdana;height:1.78em;padding-top:2px}#b{height:30px;padding-top:4px}#b,#b a{color:#77c}#u{padding-right:10px;line-height:19px;text-align:right;margin:0 0 3px !important;margin:0 0 10px}#sb{height:2em;width:5.6em}#km{height:50px}#l{margin:0 0 5px 15px}#l td{padding-left:107px}p,table{width:650px;border:0}#l td,#sb,#km{font-size:14px}#l a,#l b{margin-right:1.14em}a{color:#00c}a:active{color:#f60}#hp{position:absolute;margin-left:6px}#lg{margin:-26px 0 -44px}#lk{width:auto;line-height:18px;vertical-align:top}form{position:relative;z-index:9}
      

  14.   

    引用:4楼:
    也不是所有的页面都有Content-Length这一个字段的, 
    有些页面不发送这个东西,而是把长度放在了body里面。
    您说的很对,例如这个页面就不返回:Content-Length
    请问如何让他返回这个字段呢?http://bbs.admin5.com/forum-404-1.html
      

  15.   


    一般不可以强制它返回这个字段,但是一样可以获得长度信息。
    HTTP头之后可能有:HTTP chunked response
    如: Chunk size: 2213 octets,表明了数据的大小。