在使用PHP的cURL扩展进行网页内容抓取时,经常会碰到目标服务器返回Gzip编码的HTML响应的情况,如果不做对应处理,获取到的内容会是一串无法识别的乱码,无法正常进行后续的解析操作。这是因为很多网站为了节省传输带宽,会在服务端开启Gzip压缩,对返回的HTML内容进行压缩后再传输给客户端,客户端需要先对压缩内容进行解码才能得到原始的HTML文本。

核心处理思路
要正确处理Gzip编码的HTML响应,核心分为两步:第一步是配置cURL请求时支持接收Gzip压缩的响应,第二步是在获取到响应后,判断响应内容是否经过Gzip压缩,如果是则进行解码操作。
第一步:配置cURL支持Gzip响应
首先需要在cURL初始化后,设置对应的请求头,告诉服务器客户端支持接收Gzip压缩的响应内容,同时需要设置cURL自动处理HTTP压缩的相关选项。以下是基础的cURL配置代码:
<?php // 初始化cURL会话 $ch = curl_init(); // 设置目标URL curl_setopt($ch, CURLOPT_URL, "https://ipipp.com/test.html"); // 设置返回响应结果而不是直接输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 设置支持接收Gzip压缩的响应,告诉服务器客户端支持gzip编码 curl_setopt($ch, CURLOPT_ENCODING, "gzip"); // 可选:设置用户代理,避免被服务器识别为爬虫拒绝请求 curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"); // 可选:设置超时时间,避免请求卡住 curl_setopt($ch, CURLOPT_TIMEOUT, 10); ?>
这里的关键是CURLOPT_ENCODING选项,设置为gzip之后,cURL会自动在请求头中添加Accept-Encoding: gzip,同时如果服务器返回的是Gzip压缩的响应,cURL会自动对其进行解码,不需要我们手动处理。不过为了兼容一些特殊情况,我们也可以手动判断并解码。
第二步:判断并解码响应内容
有时候服务器可能不会严格按照请求头返回压缩内容,或者部分环境下cURL的自动解码没有生效,这时候就需要我们手动判断响应是否经过Gzip压缩,再进行对应处理。我们可以通过检查响应头中的Content-Encoding字段来判断,也可以通过响应内容的二进制特征来判断。
以下是手动判断并解码的完整示例代码:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://ipipp.com/test.html");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 同时获取响应头信息,方便判断编码类型
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_ENCODING, "gzip");
// 执行请求
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo "cURL请求错误:" . curl_error($ch);
curl_close($ch);
exit;
}
// 获取响应头大小
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
// 分割响应头和响应体
$header = substr($response, 0, $headerSize);
$body = substr($response, $headerSize);
curl_close($ch);
// 解析响应头,获取Content-Encoding字段
$headers = explode("rn", $header);
$contentEncoding = "";
foreach ($headers as $item) {
if (stripos($item, "Content-Encoding:") === 0) {
$contentEncoding = trim(str_replace("Content-Encoding:", "", $item));
break;
}
}
// 判断是否是gzip编码
if (strtolower($contentEncoding) === "gzip") {
// 使用gzdecode函数解码,需要PHP开启zlib扩展
$decodedBody = gzdecode($body);
if ($decodedBody !== false) {
$body = $decodedBody;
} else {
// 如果gzdecode失败,尝试用gzuncompress处理
$body = gzuncompress($body);
}
}
// 输出最终的HTML内容
echo $body;
?>
常见问题说明
- 如果执行代码时报
gzdecode函数不存在,需要检查PHP是否开启了zlib扩展,在php.ini中添加extension=zlib并重启服务即可。 - 部分服务器可能返回的是deflate编码的响应,这时候可以将
CURLOPT_ENCODING设置为空字符串,cURL会自动处理所有支持的压缩编码类型。 - 如果抓取的是本地测试地址比如
127.0.0.1或者192.168.0.1的内容,不需要修改地址,直接正常使用即可。
总结
处理PHP cURL获取的Gzip编码HTML响应,最简单的方式是直接设置CURLOPT_ENCODING为gzip,让cURL自动处理解码工作。如果需要更高的兼容性,可以手动获取响应头判断编码类型,再调用对应的解码函数处理。只要按照上述步骤配置和处理,就能稳定获取到正常的HTML内容,避免乱码问题。
PHPcURLGzip_encodingHTML_responseHTTP_compression修改时间:2026-06-18 05:51:34