Python解压XML文件CDATA段gz压缩串报BadGzipFile错误
问题根因
报错本质是压缩格式和解压接口不匹配:
- 报错提示的
b'x\xda'是zlib格式压缩数据的典型文件头(对应最高压缩级别的zlib封装),而gzip格式压缩数据的标准头固定为b'\x1f\x8b',两者虽然底层都使用DEFLATE压缩算法,但封装结构完全不同,无法用gzip.decompress接口解压zlib格式的数据。 - 你之前尝试直接把CDATA内的字符串传给
gzip.decompress也无法运行,是因为所有Python压缩/解压接口的入参要求是字节类型(bytes),直接传入字符串类型会触发类型错误,且传入的内容本身是base64编码的文本,不是压缩后的二进制流。
涉及的XML文件结构参考:
修复方案
按如下流程调整代码即可正常处理:
- 读取CDATA段内的文本内容,先做base64解码,得到压缩后的二进制字节流
- 换用
zlib模块的解压接口处理解码后的二进制数据,替换原有的gzip解压逻辑 - 若最终需要输出明文对应的base64编码字符串,对解压得到的明文字节流做base64编码即可
可直接运行的参考代码:
import xml.etree.ElementTree as ElementTree import binascii import zlib import base64 tree = ElementTree.parse("MYMGFILE.xml") root = tree.getroot() # 读取CDATA段存储的base64编码压缩文本 cdata_text = root[0].text # Base64解码得到压缩后的二进制数据 compressed_data = binascii.a2b_base64(cdata_text) # 用zlib接口解压,适配x\xda开头的zlib格式 plain_data = zlib.decompress(compressed_data) # 若需要最终输出base64编码的结果,执行以下转换 final_base64_result = base64.b64encode(plain_data).decode("utf-8")
补充说明
- 若运行zlib解压时依旧报头校验错误,可调整wbits参数适配裸DEFLATE流:
zlib.decompress(compressed_data, wbits=-15),该参数会跳过封装头校验,直接解压裸DEFLATE数据,适配少数非标准封装的压缩内容。 - 原代码中赋值后未使用的
file变量属于冗余代码,可直接删除避免逻辑混淆。
内容的提问来源于stack exchange,提问作者Rene Albrecht
相关产品推荐
相关产品推荐

