Python中解析前编辑HTTPResponse的方法:处理XML无效字符
解决HTTPResponse转XML时的无效字符问题
核心问题分析
直接用et.parse(url)失败,是因为返回的XML内容包含XML规范不允许的无效字符(比如控制字符、格式错误的实体引用);而你之前用str(r.content)处理会导致字节转字符串时引入额外转义(比如b'...'标识),自然无法转回有效XML。
正确处理步骤
1. 正确获取并解码响应内容
不要直接把r.content转成字符串,先按响应的编码解码成正确文本:
import requests import re from xml.etree import ElementTree as et # 获取响应并解码 r = requests.get(detailed_report_url) # 优先用响应头指定的编码,无则默认utf-8 xml_str = r.content.decode(r.encoding or 'utf-8')
2. 清除/替换XML无效字符
XML 1.0规范禁止的字符包括\x00-\x08、\x0B-\x0C、\x0E-\x1F等控制字符,以及格式错误的实体引用,用正则针对性处理:
移除控制字符
# 过滤XML不允许的控制字符 xml_cleaned = re.sub(r'[\x00-\x08\x0B\x0C\x0E-\x1F]', '', xml_str)
修复/替换错误实体引用
如果是格式不完整的实体(比如&#abc缺分号),先补全;如果是无效实体名称,替换为合法占位符:
# 补全不完整的实体引用(如&#abc → &#abc;) xml_cleaned = re.sub(r'&#([a-zA-Z0-9]+)(?!;)', r'&#\1;', xml_cleaned) # 将无法解析的实体替换为占位符(可根据需求调整逻辑) xml_cleaned = re.sub(r'&#([^;]+);', lambda m: f'[INVALID_ENTITY:{m.group(1)}]', xml_cleaned)
3. 解析XML并保存处理后的内容
清理完成后即可正常解析,同时保存处理后的XML文件:
# 解析清理后的XML字符串 root = et.fromstring(xml_cleaned) # 保存处理后的XML到文件 tree = et.ElementTree(root) with open('cleaned_report.xml', 'wb') as f: tree.write(f, encoding='utf-8', xml_declaration=True)
补充:urllib的替代处理方案
如果想继续使用urllib,可以先读取内容清理后再解析:
import urllib.request with urllib.request.urlopen(detailed_report_url) as url: xml_bytes = url.read() # 按响应编码解码 xml_str = xml_bytes.decode(url.info().get_content_charset() or 'utf-8') # 执行清理步骤 xml_cleaned = re.sub(r'[\x00-\x08\x0B\x0C\x0E-\x1F]', '', xml_str) root = et.fromstring(xml_cleaned)
关键注意点
- 不要直接对
bytes类型用str(),会引入b'...'包裹破坏XML结构 - 解码时必须匹配响应的实际编码,避免乱码
- 处理无效字符时,根据实际业务场景选择移除或替换,不要盲目修改实体引用
内容的提问来源于stack exchange,提问作者Chana Einhorn
相关产品推荐
相关产品推荐

