You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

socket下载网页时gzip编码HTTP响应解压失败问题咨询

问题原因

你遇到的报错是两个操作错误共同导致的:

  1. 响应头存在Transfer-Encoding: chunked字段,说明返回的响应体是分块传输格式,你看到的272b是当前分块的十六进制长度标识,并非gzip内容的一部分,你直接将这部分和gzip内容一起保存,自然会触发gzip格式校验失败。
  2. 你使用decode("utf-8", "ignore")处理包含gzip二进制的响应数据,会直接破坏gzip的二进制结构,就算提前剥离分块标识也无法正常解压,整个处理流程必须基于原始二进制数据完成,不能随意转字符串。
正确处理步骤
  • 全程接收socket返回的原始二进制数据,不要执行任何decode操作
  • 以b'\r\n\r\n'为分隔符切割二进制数据,前半部分为HTTP响应头,后半部分为带分块标识的响应体
  • 解析分块格式,提取纯gzip压缩数据:
    分块传输的格式规则为:[十六进制块长度]\r\n[对应长度的二进制内容]\r\n,重复该结构直到遇到长度为0的终止块。你需要循环读取每块的长度,截取对应长度的二进制内容拼接,得到的就是完整的gzip压缩数据。
  • 直接用gzip或者zlib模块解压提取到的纯gzip数据即可得到原始HTML内容。
示例修复代码
import socket
import zlib

port = 80
# 假设ip、path、website变量已赋值
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
http_message = "GET /" + path + " HTTP/1.1\r\n"
http_message += "Host: " + website + "\r\n"
http_message += "Accept: text/html\r\n"
http_message += "Accept-Language: en-US,en;q=0.9\r\n"
http_message += "Accept-Encoding: gzip, deflate\r\n"
http_message += "User-Agent: Chrome/92.0.4515.131 Mozilla/5.0 (X11; Linux x86_64)\r\n"
http_message += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n"
# 不需要长连接建议直接设为close,避免接收多余数据
http_message += "Connection: close\r\n"
http_message += "\r\n"

sock.send(http_message.encode())
# 接收完整二进制响应
raw_data = b''
while True:
    chunk = sock.recv(4096)
    if not chunk:
        break
    raw_data += chunk
sock.close()

# 拆分响应头和响应体
header_end = raw_data.find(b'\r\n\r\n')
response_header = raw_data[:header_end].decode('utf-8')
response_body = raw_data[header_end+4:]

# 解析分块内容
gzip_data = b''
offset = 0
while True:
    # 读取分块长度行
    line_end = response_body.find(b'\r\n', offset)
    if line_end == -1:
        break
    # 转换十六进制长度为十进制
    chunk_len = int(response_body[offset:line_end].decode('utf-8'), 16)
    if chunk_len == 0:
        break
    # 截取当前块的gzip内容
    gzip_data += response_body[line_end+2 : line_end+2+chunk_len]
    # 移动偏移到下一个块
    offset = line_end + 2 + chunk_len + 2

# 解压gzip内容,16+zlib.MAX_WBITS参数用于识别gzip格式
html_content = zlib.decompress(gzip_data, 16+zlib.MAX_WBITS).decode('utf-8')
print(html_content)

内容的提问来源于stack exchange,提问作者Aditya Verma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 21:21:02