错误1:Unable to parse URL
错误2:The requested URL /o.cgi was not found on this server.
但是这些fetch的这些url在浏览器里都可以访问

解决方案 »

  1.   

    <? 
    include "Snoopy.class.php"; 
    $snoopy = new Snoopy; 
    $snoopy->fetch("http://www.google.cn/url?ct=pro&cd=4&source=cwh&q=http%3A%2F%2Fwww.google.cn%2Fmusic"); 
    print_r($snoopy->results); 
    ?>
    就比如这个谷歌音乐的
      

  2.   

    有些server端会验证user-agent和referer等http头信息,就是判断你是用浏览器正常浏览还是用程序模拟的http请求,你伪造一下这些头信息就可以骗过去了。
      

  3.   

    snoopy我没用过,不过应该可以有相关的方法可以添加那些头信息。用curl的话$cookie_jar = '/tmp/cookie.tmp';function request($url,$postfields,$cookie_jar,$referer){
    $ch = curl_init();
    $options = array(CURLOPT_URL => $url,
          CURLOPT_HEADER => 0,
          CURLOPT_NOBODY => 0,
          CURLOPT_PORT => 80,
          CURLOPT_POST => 1,
          CURLOPT_POSTFIELDS => $postfields,
          CURLOPT_RETURNTRANSFER => 1,
          CURLOPT_FOLLOWLOCATION => 1,
          CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)',
          CURLOPT_COOKIEJAR => $cookie_jar,
          CURLOPT_COOKIEFILE => $cookie_jar,
          CURLOPT_REFERER => $referer
    );
    curl_setopt_array($ch, $options);
    $code = curl_exec($ch);
    curl_close($ch);
    return $code;
    }
    看到CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)',这行了吗?这就是伪造的,让server认为,我是用浏览器访问的,如果你不设置这个,对方肯定知道你是用程序模拟的。至于CURLOPT_REFERER => $referer,这个你随便写个与你访问url同域的url就可以了。
      

  4.   

    刚才我用sniffer抓包了一下。
    发现你上面的那个google的音乐地址必须用GET协议访问,否则google就会返回Method Not Allowed。
    <?php
    $cookie_jar = '/tmp/cookie.tmp';function request($url,$cookie_jar,$referer){
    $ch = curl_init();
    $options = array(CURLOPT_URL => $url,
          CURLOPT_HEADER => 0,
          CURLOPT_NOBODY => 0,
          CURLOPT_PORT => 80,
          CURLOPT_POST => 0,
          CURLOPT_RETURNTRANSFER => 1,
          CURLOPT_FOLLOWLOCATION => 1,
          CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)',
          CURLOPT_COOKIEJAR => $cookie_jar,
          CURLOPT_COOKIEFILE => $cookie_jar,
          CURLOPT_REFERER => $referer
    );
    curl_setopt_array($ch, $options);
    $code = curl_exec($ch);
    curl_close($ch);
    return $code;
    } $url = 'http://www.google.cn/url?ct=pro&cd=4&source=cwh&q=http://www.google.cn/music';
    $response = request($url,$cookie_jar,'http://www.google.cn/');
    echo $response;
    ?>
    使用上面的代码测试成功
      

  5.   

    ShadowSniper先谢谢了,第二天才能加分.
    我不会php,请告诉我上面代码能不能改成把抓取后的html以字符串的形式输出.
    明天给两百分,能不能加下我qq 691697
      

  6.   

    最后一行的echo $response;
    看到这个$response了吧,它就是抓取后的html源代码串。你愿意怎么处理都可以。但是必须提醒你下,google的这个做了防抓取措施。
    抓取到的这些源代码中并没有歌曲列表里面歌曲的链接地址以及名称,不信你用浏览器去打开那个地址,鼠标移动到歌曲名称上,观察下面的url,并不显示链接地址,点击后,他会触发js来解析出这个地址。
    原理是这样的:你提交http请求后,它返回给客户端的是一个加密的串。然后它用事先写好的js解密进行解密后才输出到页面上的。如果你想抓取它的歌曲链接,必须先找到它那个js解密函数(可能在html源代码中某个<script src="*.js" />中)
    然后用php仿照那个函数写一个。这样,服务器端返回给客户端加密串后,你的php代替js解密,就可以得到实际的链接地址了。这个比较麻烦,要一步步去分析。不过可以肯定的是,一定能够抓到。