抓取经过gzip压缩的网页内容

file_get_contents直接抓取土豆 输出是乱码

用firebug查看头部 发现Content-Encoding gzip 页面是经过gzip压缩的

需要使用gzdecode进行解压缩输出

http://www.php.net/manual/zh/function.gzdecode.php

PHP代码
  1. <?php  
  2.   
  3. function gzdecode($data) {  
  4.   $len = strlen($data);  
  5.   if ($len < 18 || strcmp(substr($data,0,2),"\x1f\x8b")) {  
  6.     return null;  // Not GZIP format (See RFC 1952)  
  7.   }  
  8.   $method = ord(substr($data,2,1));  // Compression method  
  9.   $flags  = ord(substr($data,3,1));  // Flags  
  10.   if ($flags & 31 != $flags) {  
  11.     // Reserved bits are set -- NOT ALLOWED by RFC 1952  
  12.     return null;  
  13.   }  
  14.   // NOTE: $mtime may be negative (PHP integer limitations)  
  15.   $mtime = unpack("V"substr($data,4,4));  
  16.   $mtime = $mtime[1];  
  17.   $xfl   = substr($data,8,1);  
  18.   $os    = substr($data,8,1);  
  19.   $headerlen = 10;  
  20.   $extralen  = 0;  
  21.   $extra     = "";  
  22.   if ($flags & 4) {  
  23.     // 2-byte length prefixed EXTRA data in header  
  24.     if ($len - $headerlen - 2 < 8) {  
  25.       return false;    // Invalid format  
  26.     }  
  27.     $extralen = unpack("v",substr($data,8,2));  
  28.     $extralen = $extralen[1];  
  29.     if ($len - $headerlen - 2 - $extralen < 8) {  
  30.       return false;    // Invalid format  
  31.     }  
  32.     $extra = substr($data,10,$extralen);  
  33.     $headerlen += 2 + $extralen;  
  34.   }  
  35.   
  36.   $filenamelen = 0;  
  37.   $filename = "";  
  38.   if ($flags & 8) {  
  39.     // C-style string file NAME data in header  
  40.     if ($len - $headerlen - 1 < 8) {  
  41.       return false;    // Invalid format  
  42.     }  
  43.     $filenamelen = strpos(substr($data,8+$extralen),chr(0));  
  44.     if ($filenamelen === false || $len - $headerlen - $filenamelen - 1 < 8) {  
  45.       return false;    // Invalid format  
  46.     }  
  47.     $filename = substr($data,$headerlen,$filenamelen);  
  48.     $headerlen += $filenamelen + 1;  
  49.   }  
  50.   
  51.   $commentlen = 0;  
  52.   $comment = "";  
  53.   if ($flags & 16) {  
  54.     // C-style string COMMENT data in header  
  55.     if ($len - $headerlen - 1 < 8) {  
  56.       return false;    // Invalid format  
  57.     }  
  58.     $commentlen = strpos(substr($data,8+$extralen+$filenamelen),chr(0));  
  59.     if ($commentlen === false || $len - $headerlen - $commentlen - 1 < 8) {  
  60.       return false;    // Invalid header format  
  61.     }  
  62.     $comment = substr($data,$headerlen,$commentlen);  
  63.     $headerlen += $commentlen + 1;  
  64.   }  
  65.   
  66.   $headercrc = "";  
  67.   if ($flags & 2) {  
  68.     // 2-bytes (lowest order) of CRC32 on header present  
  69.     if ($len - $headerlen - 2 < 8) {  
  70.       return false;    // Invalid format  
  71.     }  
  72.     $calccrc = crc32(substr($data,0,$headerlen)) & 0xffff;  
  73.     $headercrc = unpack("v"substr($data,$headerlen,2));  
  74.     $headercrc = $headercrc[1];  
  75.     if ($headercrc != $calccrc) {  
  76.       return false;    // Bad header CRC  
  77.     }  
  78.     $headerlen += 2;  
  79.   }  
  80.   
  81.   // GZIP FOOTER - These be negative due to PHP's limitations  
  82.   $datacrc = unpack("V",substr($data,-8,4));  
  83.   $datacrc = $datacrc[1];  
  84.   $isize = unpack("V",substr($data,-4));  
  85.   $isize = $isize[1];  
  86.   
  87.   // Perform the decompression:  
  88.   $bodylen = $len-$headerlen-8;  
  89.   if ($bodylen < 1) {  
  90.     // This should never happen - IMPLEMENTATION BUG!  
  91.     return null;  
  92.   }  
  93.   $body = substr($data,$headerlen,$bodylen);  
  94.   $data = "";  
  95.   if ($bodylen > 0) {  
  96.     switch ($method) {  
  97.       case 8:  
  98.         // Currently the only supported compression method:  
  99.         $data = gzinflate($body);  
  100.         break;  
  101.       default:  
  102.         // Unknown compression method  
  103.         return false;  
  104.     }  
  105.   } else {  
  106.     // I'm not sure if zero-byte body content is allowed.  
  107.     // Allow it for now...  Do nothing...  
  108.   }  
  109.   
  110.   // Verifiy decompressed size and CRC32:  
  111.   // NOTE: This may fail with large data sizes depending on how  
  112.   //       PHP's integer limitations affect strlen() since $isize  
  113.   //       may be negative for large sizes.  
  114.   if ($isize != strlen($data) || crc32($data) != $datacrc) {  
  115.     // Bad format!  Length or CRC doesn't match!  
  116.     return false;  
  117.   }  
  118.   return $data;  
  119. }  
  120.   
  121. ?>  

Tags: gzip

上一篇: 不同服务器上mysql如何实现同步备份   下一篇: preg_match的isU代表什么意义

提交疑问

回顶部