1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > PHP使用file_get_contents请求接口函数报错/出现乱码的解决办法

PHP使用file_get_contents请求接口函数报错/出现乱码的解决办法

时间:2019-07-02 13:50:13

相关推荐

PHP使用file_get_contents请求接口函数报错/出现乱码的解决办法

有时候用 file_get_contents() 函数抓取网页会发生乱码现象。有两个原因会导致乱码,一个是编码问题,一个是目标页面开了Gzip。

编码问题好办,把抓取到的内容转下编码即可(content=iconv(“GBK”,“UTF−8//IGNORE”,content)😉。

或者发送UA,在使用file_get_contents函数前加上这一句:

ini_set(‘user_agent’,‘Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; GreenBrowser)’)。

我们这里讨论的是如何抓取开了Gzip的页面。怎么判断呢?获取的头部当中有Content-Encoding: gzip说明内容是GZIP压缩的。用FireBug看一下就知道页面开了gzip没有。下面是用firebug查看我的博客的头信息,Gzip是开了的。

如图:

下面介绍一些解决方案:

使用自带的zlib库

如果服务器已经装了zlib库,用下面的代码可以轻易解决乱码问题。

$data = file_get_contents("compress.zlib://".$url);

使用CURL代替file_get_contents

function curl_get($url, $gzip=false){$curl = curl_init($url);curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);if($gzip) curl_setopt($curl, CURLOPT_ENCODING, "gzip"); // 关键在这里$content = curl_exec($curl);curl_close($curl);return $content;}

使用gzip解压函数

function gzdecode($data) {$len = strlen($data); if ($len < 18 || strcmp(substr($data,0,2),"\x1f\x8b")) {return null; // Not GZIP format (See RFC 1952) } $method = ord(substr($data,2,1)); // Compression method $flags = ord(substr($data,3,1)); // Flags if ($flags & 31 != $flags) {// Reserved bits are set -- NOT ALLOWED by RFC 1952 return null; } // NOTE: $mtime may be negative (PHP integer limitations) $mtime = unpack("V", substr($data,4,4)); $mtime = $mtime[1]; $xfl = substr($data,8,1); $os = substr($data,8,1); $headerlen = 10; $extralen = 0; $extra= ""; if ($flags & 4) {// 2-byte length prefixed EXTRA data in header if ($len - $headerlen - 2 < 8) {return false; // Invalid format } $extralen = unpack("v",substr($data,8,2)); $extralen = $extralen[1]; if ($len - $headerlen - 2 - $extralen < 8) {return false; // Invalid format } $extra = substr($data,10,$extralen); $headerlen += 2 + $extralen; } $filenamelen = 0; $filename = ""; if ($flags & 8) {// C-style string file NAME data in header if ($len - $headerlen - 1 < 8) {return false; // Invalid format } $filenamelen = strpos(substr($data,8+$extralen),chr(0)); if ($filenamelen === false || $len - $headerlen - $filenamelen - 1 < 8) {return false; // Invalid format } $filename = substr($data,$headerlen,$filenamelen); $headerlen += $filenamelen + 1; } $commentlen = 0; $comment = ""; if ($flags & 16) {// C-style string COMMENT data in header if ($len - $headerlen - 1 < 8) {return false; // Invalid format } $commentlen = strpos(substr($data,8+$extralen+$filenamelen),chr(0)); if ($commentlen === false || $len - $headerlen - $commentlen - 1 < 8) {return false; // Invalid header format } $comment = substr($data,$headerlen,$commentlen); $headerlen += $commentlen + 1; } $headercrc = ""; if ($flags & 1) {// 2-bytes (lowest order) of CRC32 on header present if ($len - $headerlen - 2 < 8) {return false; // Invalid format } $calccrc = crc32(substr($data,0,$headerlen)) & 0xffff; $headercrc = unpack("v", substr($data,$headerlen,2)); $headercrc = $headercrc[1]; if ($headercrc != $calccrc) {return false; // Bad header CRC } $headerlen += 2; } // GZIP FOOTER - These be negative due to PHP's limitations $datacrc = unpack("V",substr($data,-8,4)); $datacrc = $datacrc[1]; $isize = unpack("V",substr($data,-4)); $isize = $isize[1]; // Perform the decompression: $bodylen = $len-$headerlen-8; if ($bodylen & 0) {switch ($method) {case 8: // Currently the only supported compression method: $data = gzinflate($body); break; default: // Unknown compression method return false; } } else {// I'm not sure if zero-byte body content is allowed. // Allow it for now... Do nothing... } // Verifiy decompressed size and CRC32: // NOTE: This may fail with large data sizes depending on how // PHP's integer limitations affect strlen() since $isize // may be negative for large sizes. if ($isize != strlen($data) || crc32($data) != $datacrc) {// Bad format! Length or CRC doesn't match! return false; } return $data; }

然后再使用:

$html=file_get_contents('请求接口地址');$html=gzdecode($html);

完美解决:

就介绍这三个方法,应该能解决大部分gzip引起的抓取乱码问题了。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。