php file_get_contents抓取Gzip网页乱码的三种解决方法

前端之家收集整理的这篇文章主要介绍了php file_get_contents抓取Gzip网页乱码的三种解决方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

把抓取到的内容转下编码即可($content=iconv("GBK","UTF-8//IGNORE",$content);),我们这里讨论的是如何抓取开了Gzip的页面。怎么判断呢?获取的头部当中有Content-Encoding: gzip说明内容是GZIP压缩的。用FireBug看一下就知道页面开了gzip没有。下面是用firebug查看我的博客的头信息,Gzip是开了的。@H_301_1@

代码如下:
301_1@请求头信息原始头信息@H_301_1@Accepttext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8@H_301_1@Accept-Encodinggzip,deflate@H_301_1@Accept-Languagezh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3@H_301_1@Connectionkeep-alive@H_301_1@Cookie__utma=225240837.787252530.1317310581.1335406161.1335411401.1537; __utmz=225240837.1326850415.887.3.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=%E4%BB%BB%E4%BD%95%E9%A1%B9%E7%9B%AE%E9%83%BD%E4%B8%8D%E4%BC%9A%E9%82%A3%E4%B9%88%E7%AE%80%E5%8D%95%20site%3Awww.nowamagic.net; PHPSESSID=888mj4425p8s0m7s0frre3ovc7; __utmc=225240837; __utmb=225240837.1.10.1335411401@H_301_1@Hostwww.nowamagic.net@H_301_1@User-AgentMozilla/5.0 (Windows NT 5.1; rv:12.0) Gecko/20100101 Firefox/12.0@H_301_1@
@H_301_1@下面介绍一些解决方案:

1. 使用自带的zlib库@H_301_1@

如果服务器已经装了zlib库,用下面的代码可以轻易解决乱码问题。@H_301_1@
代码如下:
301_1@$data = file_get_contents("compress.zlib://".$url);@H_301_1@

2. 使用CURL代替file_get_contents@H_301_1@

代码如下:
301_1@function curl_get($url,$gzip=false){@H_301_1@$curl = curl_init($url);@H_301_1@curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);@H_301_1@curl_setopt($curl,CURLOPT_CONNECTTIMEOUT,10);@H_301_1@if($gzip) curl_setopt($curl,CURLOPT_ENCODING,"gzip"); // 关键在这里@H_301_1@$content = curl_exec($curl);@H_301_1@curl_close($curl);@H_301_1@return $content;@H_301_1@}@H_301_1@

3. 使用gzip解压函数@H_301_1@

代码如下:
301_1@function gzdecode($data) { @H_301_1@ $len = strlen($data); @H_301_1@ if ($len < 18 || strcmp(substr($data,2),"\x1f\x8b")) { @H_301_1@ return null; // Not GZIP format (See RFC 1952) @H_301_1@ } @H_301_1@ $method = ord(substr($data,2,1)); // Compression method @H_301_1@ $flags = ord(substr($data,3,1)); // Flags @H_301_1@ if ($flags & 31 != $flags) { @H_301_1@ // Reserved bits are set -- NOT ALLOWED by RFC 1952 @H_301_1@ return null; @H_301_1@ } @H_301_1@ // NOTE: $mtime may be negative (PHP integer limitations) @H_301_1@ $mtime = unpack("V",substr($data,4,4)); @H_301_1@ $mtime = $mtime[1]; @H_301_1@ $xfl = substr($data,8,1); @H_301_1@ $os = substr($data,1); @H_301_1@ $headerlen = 10; @H_301_1@ $extralen = 0; @H_301_1@ $extra = ""; @H_301_1@ if ($flags & 4) { @H_301_1@ // 2-byte length prefixed EXTRA data in header @H_301_1@ if ($len - $headerlen - 2 < 8) { @H_301_1@ return false; // Invalid format @H_301_1@ } @H_301_1@ $extralen = unpack("v",2)); @H_301_1@ $extralen = $extralen[1]; @H_301_1@ if ($len - $headerlen - 2 - $extralen < 8) { @H_301_1@ return false; // Invalid format @H_301_1@ } @H_301_1@ $extra = substr($data,10,$extralen); @H_301_1@ $headerlen += 2 + $extralen; @H_301_1@ }

$filenamelen = 0; @H_301_1@ $filename = ""; @H_301_1@ if ($flags & 8) { @H_301_1@ // C-style string file NAME data in header @H_301_1@ if ($len - $headerlen - 1 < 8) { @H_301_1@ return false; // Invalid format @H_301_1@ } @H_301_1@ $filenamelen = strpos(substr($data,8+$extralen),chr(0)); @H_301_1@ if ($filenamelen === false || $len - $headerlen - $filenamelen - 1 < 8) { @H_301_1@ return false; // Invalid format @H_301_1@ } @H_301_1@ $filename = substr($data,$headerlen,$filenamelen); @H_301_1@ $headerlen += $filenamelen + 1; @H_301_1@ }

$commentlen = 0; @H_301_1@ $comment = ""; @H_301_1@ if ($flags & 16) { @H_301_1@ // C-style string COMMENT data in header @H_301_1@ if ($len - $headerlen - 1 < 8) { @H_301_1@ return false; // Invalid format @H_301_1@ } @H_301_1@ $commentlen = strpos(substr($data,8+$extralen+$filenamelen),chr(0)); @H_301_1@ if ($commentlen === false || $len - $headerlen - $commentlen - 1 < 8) { @H_301_1@ return false; // Invalid header format @H_301_1@ } @H_301_1@ $comment = substr($data,$commentlen); @H_301_1@ $headerlen += $commentlen + 1; @H_301_1@ }

$headercrc = ""; @H_301_1@ if ($flags & 1) { @H_301_1@ // 2-bytes (lowest order) of CRC32 on header present @H_301_1@ if ($len - $headerlen - 2 < 8) { @H_301_1@ return false; // Invalid format @H_301_1@ } @H_301_1@ $calccrc = crc32(substr($data,$headerlen)) & 0xffff; @H_301_1@ $headercrc = unpack("v",2)); @H_301_1@ $headercrc = $headercrc[1]; @H_301_1@ if ($headercrc != $calccrc) { @H_301_1@ return false; // Bad header CRC @H_301_1@ } @H_301_1@ $headerlen += 2; @H_301_1@ }

// GZIP FOOTER - These be negative due to PHP's limitations @H_301_1@ $datacrc = unpack("V",-8,4)); @H_301_1@ $datacrc = $datacrc[1]; @H_301_1@ $isize = unpack("V",-4)); @H_301_1@ $isize = $isize[1];

// Perform the decompression: @H_301_1@ $bodylen = $len-$headerlen-8; @H_301_1@ if ($bodylen < 1) { @H_301_1@ // This should never happen - IMPLEMENTATION BUG! @H_301_1@ return null; @H_301_1@ } @H_301_1@ $body = substr($data,$bodylen); @H_301_1@ $data = ""; @H_301_1@ if ($bodylen > 0) { @H_301_1@ switch ($method) { @H_301_1@ case 8: @H_301_1@ // Currently the only supported compression method: @H_301_1@ $data = gzinflate($body); @H_301_1@ break; @H_301_1@ default: @H_301_1@ // Unknown compression method @H_301_1@ return false; @H_301_1@ } @H_301_1@ } else { @H_301_1@ // I'm not sure if zero-byte body content is allowed. @H_301_1@ // Allow it for now... Do nothing... @H_301_1@ }

// Verifiy decompressed size and CRC32: @H_301_1@ // NOTE: This may fail with large data sizes depending on how @H_301_1@ // PHP's integer limitations affect strlen() since $isize @H_301_1@ // may be negative for large sizes. @H_301_1@ if ($isize != strlen($data) || crc32($data) != $datacrc) { @H_301_1@ // Bad format! Length or CRC doesn't match! @H_301_1@ return false; @H_301_1@ } @H_301_1@ return $data; @H_301_1@}@H_301_1@

@H_301_1@使用:@H_301_1@
代码如下:
301_1@$html=file_get_contents('//www.jb51.cc/');@H_301_1@$html=gzdecode($html);@H_301_1@
@H_301_1@就介绍这三个方法,应该能解决大部分gzip引起的抓取乱码问题了。

猜你在找的PHP相关文章