使用Requests解码application/x-gzip格式响应的技术求助
解决Requests下载GZ压缩XML文件的解码问题
我用Requests库从网站下载打包为GZ压缩文件的EPG XML数据,折腾了一整夜都没成功解码,试过切换UTF-8和ISO-8859-1编码,结果还是乱码。
当前代码片段:
import xml.etree.ElementTree as ET import requests import gzip url = 'http://example.com' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' 'AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/102.0.0.0 Safari/537.36' } def import_xml() -> list: try: response = requests.get(url, headers=headers, stream=True) print(response) print(response.headers['Content-Type']) print(response.encoding) print(response.text[:100]) print(response.content[:100]) data = import_xml
执行代码后输出:
<Response [200]> application/x-gzip None ��v�J�-�~�8��^��%�u�vuI�/�����z*��HX ���o�?��t����;s��I� ,[�K{��e�@�̌��1#�����4 b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x0b\xec\xbd\xdbv\xdbJ\x92-\xfa~\xc68\xff\x80^\x0f\xed\xee\xb1%\x97u\xf1\xbavu\x0fI\xbe/\xcb\xf6\xb6\xb4\xec\xaaz*\x90\x84HX \xc0\x02\x08\xc9\xf4o\xec?\xd8\xfdt\x1e\xce\xf9\x88\xae\x1f;s\xce\xc8\x04I\x98\x00\x05,[\x1e\xbbK{\x8f\xaee\x9b@\x02\x88\xcc\x8c\x8c\x981#\xe2\xdf'
问题原因
输出里的response.content开头是\x1f\x8b,这是GZIP压缩文件的标志性魔数,说明你拿到的是二进制压缩数据,直接用response.text会把二进制数据当成文本解码,必然出现乱码,和编码格式无关。
修正方案
需要先解压二进制数据,再解析XML,修正后的代码如下:
import xml.etree.ElementTree as ET import requests import gzip from io import BytesIO url = 'http://example.com' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' 'AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/102.0.0.0 Safari/537.36' } def import_xml() -> list: try: response = requests.get(url, headers=headers) # 检查响应是否成功 response.raise_for_status() # 将二进制响应内容转为BytesIO对象,供gzip解压 compressed_data = BytesIO(response.content) # 解压数据,得到XML文本 with gzip.GzipFile(fileobj=compressed_data, mode='rb') as f: xml_content = f.read().decode('utf-8') # 可根据实际XML编码调整,通常为UTF-8 # 解析XML root = ET.fromstring(xml_content) # 示例:提取所有频道名称(需根据实际XML结构调整) channels = [channel.find('display-name').text for channel in root.findall('channel')] return channels except Exception as e: print(f"处理出错: {e}") return [] data = import_xml() print(data)
关键修改点
- 用
response.content获取二进制压缩数据,避免response.text的错误解码 - 用
BytesIO将二进制数据转为文件对象,配合gzip.GzipFile完成解压 - 解压后用对应编码(通常为UTF-8)解码为XML文本,再进行节点解析
- 增加异常处理,捕获请求或解压过程中的错误
内容的提问来源于stack exchange,提问作者baugen
相关产品推荐
相关产品推荐

